summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG18
-rw-r--r--Rakefile2
-rwxr-xr-xbin/puppetd32
-rw-r--r--ext/emacs/puppet-mode.el30
-rwxr-xr-xinstall.rb4
-rw-r--r--lib/puppet/executables/client/certhandler.rb70
-rw-r--r--lib/puppet/indirector/indirection.rb2
-rw-r--r--lib/puppet/indirector/request.rb25
-rw-r--r--lib/puppet/network/handler/master.rb24
-rw-r--r--lib/puppet/network/http/handler.rb55
-rw-r--r--lib/puppet/network/http/mongrel/rest.rb41
-rw-r--r--lib/puppet/network/http/webrick/rest.rb51
-rw-r--r--lib/puppet/node.rb59
-rw-r--r--lib/puppet/parser/collector.rb6
-rw-r--r--lib/puppet/parser/grammar.ra4
-rw-r--r--lib/puppet/parser/parser.rb8
-rw-r--r--lib/puppet/provider/package/pkgdmg.rb61
-rw-r--r--lib/puppet/rails/database/001_add_created_at_to_all_tables.rb28
-rw-r--r--lib/puppet/sslcertificates/ca.rb13
-rw-r--r--lib/puppet/util/resource_template.rb61
-rwxr-xr-xspec/integration/indirector/rest.rb33
-rwxr-xr-xspec/integration/network/server/mongrel.rb74
-rwxr-xr-xspec/integration/network/server/webrick.rb6
-rw-r--r--spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb46
-rw-r--r--spec/spec_helper.rb2
-rwxr-xr-xspec/unit/executables/client/certhandler.rb88
-rwxr-xr-xspec/unit/indirector/indirection.rb8
-rwxr-xr-xspec/unit/indirector/module_files.rb36
-rwxr-xr-xspec/unit/indirector/request.rb32
-rwxr-xr-x[-rw-r--r--]spec/unit/network/client.rb0
-rwxr-xr-x[-rw-r--r--]spec/unit/network/http.rb0
-rwxr-xr-x[-rw-r--r--]spec/unit/network/http/mongrel.rb0
-rwxr-xr-x[-rw-r--r--]spec/unit/network/http/mongrel/rest.rb166
-rwxr-xr-x[-rw-r--r--]spec/unit/network/http/mongrel/xmlrpc.rb0
-rwxr-xr-x[-rw-r--r--]spec/unit/network/http/webrick.rb2
-rwxr-xr-x[-rw-r--r--]spec/unit/network/http/webrick/rest.rb167
-rwxr-xr-x[-rw-r--r--]spec/unit/network/http/webrick/xmlrpc.rb0
-rwxr-xr-x[-rw-r--r--]spec/unit/network/server.rb0
-rwxr-xr-xspec/unit/node.rb112
-rwxr-xr-xspec/unit/parser/collector.rb9
-rwxr-xr-xspec/unit/util/resource_template.rb58
-rwxr-xr-x[-rw-r--r--]spec/unit/util/warnings.rb0
-rw-r--r--test/lib/rake/puppet_testtask.rb3
-rwxr-xr-xtest/network/client/ca.rb1
-rwxr-xr-xtest/network/client/master.rb14
-rwxr-xr-xtest/network/handler/master.rb86
46 files changed, 999 insertions, 538 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 5ee44775f..8a2344724 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,6 +3,24 @@
whether we should even use a CRL. This way we aren't trying to
set file paths to 'false' to disable the CRL.
+ Adding a ResourceTemplate class for using templates directly
+ within resources (i.e., client-side templates). This would really
+ only be used for composite resources that pass the results of the
+ template on to generated resources.
+
+ Exporting or collecting resources no longer raises an exception
+ when no storeconfigs is enabled, it just produces a warning.
+
+ Always using the cert name to store yaml files, which fixes #1178.
+ The Master handler previously provided the support for the :node_name
+ setting, and that functionality has now been moved into the Node
+ class. At the same time, the names to search through have been
+ changed somewhat: Previously, the certificate name and the
+ hostname were both used for searching, but now, the cert name
+ is always searched first (unless node_name == facter), but only
+ the Facter hostname, domain, and fqdn are used otherwise. We no
+ longer split the cert name, only the hostname/domain/fqdn.
+
Fixing transaction support for prefetching generated resources.
Adding support for settings within the existing Facter provider confines.
diff --git a/Rakefile b/Rakefile
index 1a3faad09..f4f88f2cc 100644
--- a/Rakefile
+++ b/Rakefile
@@ -23,7 +23,7 @@ project = Rake::RedLabProject.new("puppet") do |p|
'lib/puppet.rb',
'lib/puppet/**/*.rb',
'lib/puppet/**/*.py',
- 'test/**/*.rb',
+ 'test/**/*',
'bin/**/*',
'ext/**/*',
'examples/**/*',
diff --git a/bin/puppetd b/bin/puppetd
index d408af7d3..c36b3ed97 100755
--- a/bin/puppetd
+++ b/bin/puppetd
@@ -162,6 +162,7 @@ trap(:INT) do
end
require 'puppet'
+require 'puppet/executables/client/certhandler'
require 'puppet/network/client'
require 'getoptlong'
@@ -347,35 +348,8 @@ if Puppet[:daemonize]
client.daemonize
end
-caclient = Puppet::Network::Client.ca.new()
-
-unless caclient.read_cert
- if options[:waitforcert] > 0
- begin
- while ! caclient.request_cert do
- Puppet.notice "Did not receive certificate"
- sleep options[:waitforcert]
- end
- rescue => detail
- Puppet.err "Could not request certificate: %s" % detail.to_s
- exit(23)
- end
- else
- unless caclient.request_cert
- Puppet.notice "No certificates; exiting"
- exit(1)
- end
- end
-
- # Now read the new cert in.
- if caclient.read_cert
- # If we read it in, then get rid of our existing http connection.
- client.recycle_connection
- Puppet.notice "Got signed certificate"
- else
- Puppet.err "Could not read certificates after retrieving them"
- exit(34)
- end
+unless Puppet::Executables::Client::CertHandler.new(options[:waitforcert], options[:onetime]).read_retrieve
+ client.recycle_connection
end
objects = []
diff --git a/ext/emacs/puppet-mode.el b/ext/emacs/puppet-mode.el
index f3f4589aa..11fcfea0a 100644
--- a/ext/emacs/puppet-mode.el
+++ b/ext/emacs/puppet-mode.el
@@ -103,15 +103,16 @@ that array, else return nil."
(let ((opoint (point))
(apoint (search-backward "[" nil t)))
(when apoint
- ;; An array opens before point. If it doesn't close before
- ;; point, then point must be in it.
- ;; ### TODO: of course, the '[' could be in a string literal,
- ;; ### in which case this whole idea is bogus. But baby
- ;; ### steps, baby steps. A more robust strategy might be
- ;; ### to walk backwards by sexps, until hit a wall, then
- ;; ### inspect the nature of that wall.
- (if (= (puppet-count-matches "\\]" apoint opoint) 0)
- apoint))))))
+ ;; This is a bit of a hack and doesn't allow for strings. We really
+ ;; want to parse by sexps at some point.
+ (let ((close-brackets (puppet-count-matches "]" apoint opoint))
+ (open-brackets 0))
+ (while (and apoint (> close-brackets open-brackets))
+ (setq apoint (search-backward "[" nil t))
+ (when apoint
+ (setq close-brackets (puppet-count-matches "]" apoint opoint))
+ (setq open-brackets (1+ open-brackets)))))
+ apoint)))))
(defun puppet-in-include ()
"If point is in a continued list of include statements, return the position
@@ -206,14 +207,14 @@ of the initial include plus puppet-include-indent."
;; Brace or paren not on a line by itself will be indented one
;; level too much, but don't catch cases where the block is
;; started and closed on the same line.
- ((looking-at "^[^\({]*[\)}]\\s-*$")
+ ((looking-at "^[^\n\({]*[\)}]\\s-*$")
(setq cur-indent (- (current-indentation) puppet-indent-level))
(setq not-indented nil))
;; Indent by one level more than the start of our block. We lose
;; if there is more than one block opened and closed on the same
;; line but it's still unbalanced; hopefully people don't do that.
- ((looking-at "^.*{[^}]*$")
+ ((looking-at "^.*{[^\n}]*$")
(setq cur-indent (+ (current-indentation) puppet-indent-level))
(setq not-indented nil))
@@ -225,7 +226,7 @@ of the initial include plus puppet-include-indent."
;; Semicolon ends a block for a resource when multiple resources
;; are defined in the same block, but try not to get the case of
;; a complete resource on a single line wrong.
- ((looking-at "^\\([^'\":\n]\\|\"[^\"]*\"\\|'[^']'\\)**;\\s-*$")
+ ((looking-at "^\\([^'\":\n]\\|\"[^\n\"]*\"\\|'[^\n']'\\)**;\\s-*$")
(setq cur-indent (- (current-indentation) puppet-indent-level))
(setq not-indented nil))
@@ -306,7 +307,6 @@ of the initial include plus puppet-include-indent."
;; variables
'("\\(^\\|[^_:.@$]\\)\\b\\(true\\|false\\)\\>"
2 font-lock-variable-name-face)
- ;; variables
'("\\(\\$\\([^a-zA-Z0-9 \n]\\|[0-9]\\)\\)\\W"
1 font-lock-variable-name-face)
'("\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\|:\\)+"
@@ -314,8 +314,8 @@ of the initial include plus puppet-include-indent."
;; usage of types
'("^\\s *\\([a-zA-Z_-]+\\)\\s +{"
1 font-lock-type-face)
- ;; overrides
- '("^\\s +\\([a-zA-Z_-]+\\)\\["
+ ;; overrides and type references
+ '("\\s +\\([A-Z][a-zA-Z_:-]*\\)\\["
1 font-lock-type-face)
;; general delimited string
'("\\(^\\|[[ \t\n<+(,=]\\)\\(%[xrqQwW]?\\([^<[{(a-zA-Z0-9 \n]\\)[^\n\\\\]*\\(\\\\.[^\n\\\\]*\\)*\\(\\3\\)\\)"
diff --git a/install.rb b/install.rb
index c32c24245..27b09397e 100755
--- a/install.rb
+++ b/install.rb
@@ -78,7 +78,7 @@ rdoc = glob(%w{bin/* sbin/* lib/**/*.rb README README-library CHANGELOG TODO In
ri = glob(%w(bin/*.rb sbin/* lib/**/*.rb)).reject { |e| e=~ /\.(bat|cmd)$/ }
man = glob(%w{man/man8/*})
libs = glob(%w{lib/**/*.rb lib/**/*.py})
-tests = glob(%w{tests/**/*.rb})
+tests = glob(%w{test/**/*.rb})
def do_bins(bins, target, strip = 's?bin/')
bins.each do |bf|
@@ -393,7 +393,7 @@ EOS
check_prereqs
prepare_installation
-run_tests(tests) if InstallOptions.tests
+#run_tests(tests) if InstallOptions.tests
#build_rdoc(rdoc) if InstallOptions.rdoc
#build_ri(ri) if InstallOptions.ri
#build_man(bins) if InstallOptions.man
diff --git a/lib/puppet/executables/client/certhandler.rb b/lib/puppet/executables/client/certhandler.rb
new file mode 100644
index 000000000..6f23de0e3
--- /dev/null
+++ b/lib/puppet/executables/client/certhandler.rb
@@ -0,0 +1,70 @@
+
+module Puppet
+ module Executables
+ module Client
+ class CertHandler
+ attr_writer :wait_for_cert, :one_time
+
+ attr_reader :caclient
+
+ def initialize(wait_time, is_one_time)
+ @wait_for_cert = wait_time
+ @one_time = is_one_time
+ @new_cert = false
+
+ @caclient = Puppet::Network::Client.ca.new()
+ end
+
+ def read_retrieve
+ #NOTE: ACS this is checking that a file exists, maybe next time just do that?
+ unless read_cert
+ # If we don't already have the certificate, then create a client to
+ # request one. Use the special ca stuff, don't use the normal server and port.
+ retrieve_cert
+ end
+
+ !@new_cert
+ end
+
+ def retrieve_cert
+ while true do
+ begin
+ if caclient.request_cert
+ break if read_new_cert
+ else
+ Puppet.notice "Did not receive certificate"
+ if @one_time
+ Puppet.notice "Set to run 'one time'; exiting with no certificate"
+ exit(1)
+ end
+ end
+ rescue StandardError => detail
+ Puppet.err "Could not request certificate: %s" % detail.to_s
+ exit(23) if @one_time
+ end
+
+ sleep @wait_for_cert
+ end
+ end
+
+ def read_cert
+ caclient.read_cert
+ end
+
+ def read_new_cert
+ if caclient.read_cert
+ # If we read it in, then we need to get rid of our existing http connection.
+ # The @new_cert flag will help us do that
+ @new_cert = true
+ Puppet.notice "Got signed certificate"
+ else
+ Puppet.err "Could not read certificates after retrieving them"
+ exit(34) if @one_time
+ end
+
+ return @new_cert
+ end
+ end
+ end
+ end
+end
diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb
index c70259304..a9fff75b8 100644
--- a/lib/puppet/indirector/indirection.rb
+++ b/lib/puppet/indirector/indirection.rb
@@ -256,7 +256,7 @@ class Puppet::Indirector::Indirection
def check_authorization(request, terminus)
# At this point, we're assuming authorization makes no sense without
# client information.
- return unless request.options[:node]
+ return unless request.node
# This is only to authorize via a terminus-specific authorization hook.
return unless terminus.respond_to?(:authorized?)
diff --git a/lib/puppet/indirector/request.rb b/lib/puppet/indirector/request.rb
index 68b7ee160..98fa38885 100644
--- a/lib/puppet/indirector/request.rb
+++ b/lib/puppet/indirector/request.rb
@@ -3,10 +3,29 @@ require 'puppet/indirector'
# Provide any attributes or functionality needed for indirected
# instances.
class Puppet::Indirector::Request
- attr_accessor :indirection_name, :key, :method, :options, :instance
+ attr_accessor :indirection_name, :key, :method, :options, :instance, :node, :ip, :authenticated
+
+ # Is this an authenticated request?
+ def authenticated?
+ # Double negative, so we just get true or false
+ ! ! authenticated
+ end
def initialize(indirection_name, method, key, options = {})
- @indirection_name, @method, @options = indirection_name, method, (options || {})
+ options ||= {}
+ raise ArgumentError, "Request options must be a hash, not %s" % options.class unless options.is_a?(Hash)
+
+ @indirection_name, @method = indirection_name, method
+
+ @options = options.inject({}) do |result, ary|
+ param, value = ary
+ if respond_to?(param.to_s + "=")
+ send(param.to_s + "=", value)
+ else
+ result[param] = value
+ end
+ result
+ end
if key.is_a?(String) or key.is_a?(Symbol)
@key = key
@@ -14,8 +33,6 @@ class Puppet::Indirector::Request
@instance = key
@key = @instance.name
end
-
- raise ArgumentError, "Request options must be a hash, not %s" % @options.class unless @options.is_a?(Hash)
end
# Look up the indirection based on the name provided.
diff --git a/lib/puppet/network/handler/master.rb b/lib/puppet/network/handler/master.rb
index 851ccc7b2..a050b089b 100644
--- a/lib/puppet/network/handler/master.rb
+++ b/lib/puppet/network/handler/master.rb
@@ -56,7 +56,8 @@ class Puppet::Network::Handler
# Call our various handlers; this handler is getting deprecated.
def getconfig(facts, format = "marshal", client = nil, clientip = nil)
facts = decode_facts(facts)
- client, clientip = clientname(client, clientip, facts)
+
+ client ||= facts["hostname"]
# Pass the facts to the fact handler
Puppet::Node::Facts.new(client, facts).save unless local?
@@ -66,27 +67,6 @@ class Puppet::Network::Handler
return translate(catalog.extract)
end
- private
-
- # Manipulate the client name as appropriate.
- def clientname(name, ip, facts)
- # Always use the hostname from Facter.
- client = facts["hostname"]
- clientip = facts["ipaddress"]
- if Puppet[:node_name] == 'cert'
- if name
- client = name
- facts["fqdn"] = client
- facts["hostname"], facts["domain"] = client.split('.', 2)
- end
- if ip
- clientip = ip
- end
- end
-
- return client, clientip
- end
-
#
def decode_facts(facts)
if @local
diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb
index c05d4907f..3c14c8a40 100644
--- a/lib/puppet/network/http/handler.rb
+++ b/lib/puppet/network/http/handler.rb
@@ -1,30 +1,30 @@
module Puppet::Network::HTTP::Handler
-
+
def initialize_for_puppet(args = {})
raise ArgumentError unless @server = args[:server]
raise ArgumentError unless @handler = args[:handler]
@model = find_model_for_handler(@handler)
end
-
+
# handle an HTTP request
def process(request, response)
return do_find(request, response) if get?(request) and singular?(request)
return do_search(request, response) if get?(request) and plural?(request)
return do_destroy(request, response) if delete?(request) and singular?(request)
- return do_save(request, response) if put?(request) and singular?(request)
+ return do_save(request, response) if put?(request) and singular?(request)
raise ArgumentError, "Did not understand HTTP #{http_method(request)} request for '#{path(request)}'"
rescue Exception => e
return do_exception(request, response, e)
end
-
+
private
def model
@model
end
-
+
def do_find(request, response)
- key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]")
+ key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path(request)}]")
args = params(request)
result = model.find(key, args).to_yaml
encode_result(request, response, result)
@@ -37,7 +37,7 @@ module Puppet::Network::HTTP::Handler
end
def do_destroy(request, response)
- key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]")
+ key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path(request)}]")
args = params(request)
result = model.destroy(key, args)
encode_result(request, response, YAML.dump(result))
@@ -46,70 +46,73 @@ module Puppet::Network::HTTP::Handler
def do_save(request, response)
data = body(request).to_s
raise ArgumentError, "No data to save" if !data or data.empty?
- # args = params(request)
+ args = params(request)
obj = model.from_yaml(data)
- result = save_object(obj).to_yaml
+ result = save_object(obj, args).to_yaml
encode_result(request, response, result)
end
-
- def save_object(obj)
- obj.save
+
+ # LAK:NOTE This has to be here for testing; it's a stub-point so
+ # we keep infinite recursion from happening.
+ def save_object(object, args)
+ object.save(args)
end
-
+
def do_exception(request, response, exception, status=404)
encode_result(request, response, exception.to_yaml, status)
end
-
+
def find_model_for_handler(handler)
Puppet::Indirector::Indirection.model(handler) ||
raise(ArgumentError, "Cannot locate indirection [#{handler}].")
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
-
+
def singular?(request)
%r{/#{@handler.to_s}$}.match(path(request))
end
-
+
def plural?(request)
%r{/#{@handler.to_s}s$}.match(path(request))
end
-
+
# methods to be overridden by the including web server class
+
def register_handler
raise NotImplementedError
end
-
+
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 encode_result(request, response, result, status = 200)
raise NotImplementedError
end
diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb
index a471a62bf..520ad67f0 100644
--- a/lib/puppet/network/http/mongrel/rest.rb
+++ b/lib/puppet/network/http/mongrel/rest.rb
@@ -3,45 +3,64 @@ require 'puppet/network/http/handler'
class Puppet::Network::HTTP::MongrelREST < Mongrel::HttpHandler
include Puppet::Network::HTTP::Handler
-
+
def initialize(args={})
super()
initialize_for_puppet(args)
end
+ # Return the query params for this request. We had to expose this method for
+ # testing purposes.
+ def params(request)
+ Mongrel::HttpRequest.query_parse(request.params["QUERY_STRING"]).merge(client_info(request))
+ end
+
private
-
+
# which HTTP verb was used in this request
def http_method(request)
request.params[Mongrel::Const::REQUEST_METHOD]
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].split('/')[1]
end
-
+
# return the key included in the request path
def request_key(request)
# LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
x = request.params[Mongrel::Const::REQUEST_PATH].split('/')[2]
end
-
+
# return the request body
def body(request)
request.body
end
-
- # return the query params for this request
- def params(request)
- Mongrel::HttpRequest.query_parse(request.params["QUERY_STRING"])
- end
-
+
# produce the body of the response
def encode_result(request, response, result, status = 200)
response.start(status) do |head, body|
body.write(result)
end
end
+
+ def client_info(request)
+ result = {}
+ params = request.params
+ result[:ip] = 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[:authenticated] = false
+ end
+
+ return result
+ end
end
diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb
index b43912196..a235fb4f3 100644
--- a/lib/puppet/network/http/webrick/rest.rb
+++ b/lib/puppet/network/http/webrick/rest.rb
@@ -1,46 +1,67 @@
require 'puppet/network/http/handler'
class Puppet::Network::HTTP::WEBrickREST < WEBrick::HTTPServlet::AbstractServlet
-
+
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)
+ raise ArgumentError, "server is required" unless server
+ super(server)
+ initialize_for_puppet(:server => server, :handler => handler)
+ end
+
+ # We had to expose this method for testing purposes.
+ def params(request)
+ result = request.query
+ 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
-
+
private
-
+
def http_method(request)
request.request_method
end
-
+
def path(request)
# LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
x = '/' + request.path.split('/')[1]
end
-
+
def request_key(request)
# LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
x = request.path.split('/')[2]
end
-
+
def body(request)
request.body
end
-
- def params(request)
- request.query
- end
-
+
def encode_result(request, response, result, status = 200)
response.status = status
response.body = 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
+
+ # 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
+ end
+
+ result
+ end
end
diff --git a/lib/puppet/node.rb b/lib/puppet/node.rb
index 252ab961e..1d2041201 100644
--- a/lib/puppet/node.rb
+++ b/lib/puppet/node.rb
@@ -18,9 +18,8 @@ class Puppet::Node
def self.find_by_any_name(key)
return nil unless key
- facts = node_facts(key)
node = nil
- names = node_names(key, facts)
+ names = node_names(key)
names.each do |name|
name = name.to_s if name.is_a?(Symbol)
break if node = find(name)
@@ -34,13 +33,16 @@ class Puppet::Node
end
end
- if node
- node.names = names
+ return nil unless node
- return node
- else
- return nil
- end
+ node.names = names
+
+ # This is critical, because it forces our node's name to always
+ # be the key, which is nearly always the node's certificate.
+ # This is how the node instance is linked to the Facts instance,
+ # so it quite matters.
+ node.name = key
+ return node
end
private
@@ -60,33 +62,34 @@ class Puppet::Node
facts ||= node_facts(key)
names = []
- if hostname = facts["hostname"]
- unless hostname == key
- names << hostname
+ # First, get the fqdn
+ unless fqdn = facts["fqdn"]
+ if domain = facts["domain"]
+ fqdn = facts["hostname"] + "." + facts["domain"]
end
- else
- hostname = key
- end
-
- if fqdn = facts["fqdn"]
- hostname = fqdn
- names << fqdn
end
- # Make sure both the fqdn and the short name of the
- # host can be used in the manifest
- if hostname =~ /\./
- names << hostname.sub(/\..+/,'')
- elsif domain = facts['domain']
- names << hostname + "." + domain
+ # Now that we (might) have the fqdn, add each piece to the name
+ # list to search, in order of longest to shortest.
+ if fqdn
+ list = fqdn.split(".")
+ tmp = []
+ list.each_with_index do |short, i|
+ tmp << list[0..i].join(".")
+ end
+ names += tmp.reverse
end
- # Sort the names inversely by name length.
- names.sort! { |a,b| b.length <=> a.length }
-
# And make sure the key is first, since that's the most
# likely usage.
- ([key] + names).uniq
+ # The key is usually the Certificate CN, but it can be
+ # set to the 'facter' hostname instead.
+ if Puppet[:node_name] == 'cert'
+ names.unshift key
+ else
+ names.unshift facts["hostname"]
+ end
+ names.uniq
end
public
diff --git a/lib/puppet/parser/collector.rb b/lib/puppet/parser/collector.rb
index 2699dc6e1..bcba9528e 100644
--- a/lib/puppet/parser/collector.rb
+++ b/lib/puppet/parser/collector.rb
@@ -6,6 +6,12 @@ class Puppet::Parser::Collector
# Call the collection method, mark all of the returned objects as non-virtual,
# and then delete this object from the list of collections to evaluate.
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
if objects = collect_resources and ! objects.empty?
return objects
diff --git a/lib/puppet/parser/grammar.ra b/lib/puppet/parser/grammar.ra
index 484efe83c..a2f6729ee 100644
--- a/lib/puppet/parser/grammar.ra
+++ b/lib/puppet/parser/grammar.ra
@@ -152,7 +152,7 @@ virtualresource: at resource {
type = val[0]
if (type == :exported and ! Puppet[:storeconfigs]) and ! Puppet[:parseonly]
- error "You cannot collect without storeconfigs being set"
+ Puppet.warning addcontext("You cannot collect without storeconfigs being set")
end
if val[1].is_a? AST::ResourceDefaults
@@ -193,7 +193,7 @@ collection: classref collectrhand {
args[:form] = val[1]
end
if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly]
- error "You cannot collect exported resources without storeconfigs being set"
+ Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored")
end
result = ast AST::Collection, args
}
diff --git a/lib/puppet/parser/parser.rb b/lib/puppet/parser/parser.rb
index e27a209fc..3d7f21dca 100644
--- a/lib/puppet/parser/parser.rb
+++ b/lib/puppet/parser/parser.rb
@@ -29,7 +29,7 @@ module Puppet
class Parser < Racc::Parser
-module_eval <<'..end grammar.ra modeval..idfef5d70c9f', 'grammar.ra', 638
+module_eval <<'..end grammar.ra modeval..id9145566289', 'grammar.ra', 638
# It got too annoying having code in a file that needs to be compiled.
require 'puppet/parser/parser_support'
@@ -41,7 +41,7 @@ require 'puppet/parser/parser_support'
# $Id$
-..end grammar.ra modeval..idfef5d70c9f
+..end grammar.ra modeval..id9145566289
##### racc 1.4.5 generates ###
@@ -958,7 +958,7 @@ module_eval <<'.,.,', 'grammar.ra', 174
type = val[0]
if (type == :exported and ! Puppet[:storeconfigs]) and ! Puppet[:parseonly]
- error "You cannot collect without storeconfigs being set"
+ Puppet.warning addcontext("You cannot collect without storeconfigs being set")
end
if val[1].is_a? AST::ResourceDefaults
@@ -1011,7 +1011,7 @@ module_eval <<'.,.,', 'grammar.ra', 199
args[:form] = val[1]
end
if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly]
- error "You cannot collect exported resources without storeconfigs being set"
+ Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored")
end
result = ast AST::Collection, args
result
diff --git a/lib/puppet/provider/package/pkgdmg.rb b/lib/puppet/provider/package/pkgdmg.rb
index 2614d0950..134be5a65 100644
--- a/lib/puppet/provider/package/pkgdmg.rb
+++ b/lib/puppet/provider/package/pkgdmg.rb
@@ -28,66 +28,7 @@
require 'puppet/provider/package'
Puppet::Type.type(:package).provide :pkgdmg, :parent => Puppet::Provider::Package do
- desc "Package management based on Apple's Installer.app and DiskUtility.app
-
-Author: Jeff McCune <jeff@northstarlabs.net>
-
-Please direct questions about this provider to the puppet-users mailing list.
-
-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.
-
-This provider always assumes the label (formerly called 'name') attribute
-declared in the manifest will always exactly match the file name (without
-path) of the DMG file itself. Therefore, if you want to install packages in
-'Foobar.pkg.dmg' you must explicitly specify the label::
-
- package { Foobar.pkg.dmg: ensure => installed, provider => pkgdmg }
-
-Only the dmg file name itself is used when puppet determines if the packages
-contained within are currently installed. For example, if a package resource
-named 'Foobar.pkg.dmg' is named for installation and contains multiple
-packages, this provider will install all packages in the root directory of
-this file system, then create a small cookie for the whole bundle, located at
-/var/db/.puppet_pkgdmg_installed_Foobar.pkg.dmg
-
-As a result, if you change the contents of the DMG file in any way, Puppet
-will not update or re-install the packages contained within unless you change
-the file name of the DMG wrapper itself. Therefore, if you use this provider,
-I recommend you name the DMG wrapper files in a manner that lends itself to
-incremental version changes. I include some version or date string in the DMG
-name, like so::
-
- Firefox-2.0.0.3-1.pkg.dmg
-
-If I realize I've mis-packaged this DMG, then I have the option to increment
-the package version, yielding Firefox-2.0.0.3-2.pkg.dmg.
-
-This provider allows you to host DMG files within an FTP or HTTP server. This
-is primarily how the author provider distributes software. Any URL mechanism
-curl or Ruby's open-uri module supports is supported by this provider. Curl
-supported URL's yield much faster data throughput than open-uri, so I
-recommend HTTP, HTTPS, or FTP for source package repositories.
-
-Because the provider assumes packages will be transfered via CURL, a two stage
-process occurs. First, if a URL is detected, curl is invoked to transfer the
-file into a temporary directory. If no URL is present, the provider skips
-straight to step 2. In step two, the source file is mounted, then packages
-installed, and finally the DMG file is removed.
-
-If this is a problem for you, please patch the code, or bug Jeff to fix this.
-
-Example usage::
-
- package { Thunderbird-2.0.0.4-1.pkg.dmg:
- provider => pkgdmg, ensure => present
- source => 'http://0.0.0.0:8000/packages/Thunderbird-2.0.0.4-1.pkg.dmg',
- }
-
-**WARNING**: Because I assume files will be downloaded to /tmp, the current
-implementation attempts to delete DMG files if you install directly from the
-file system and not via a URL method."
+ 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 :exists => "/Library/Receipts"
commands :installer => "/usr/sbin/installer"
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 71ee6aeed..d1035b0db 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,17 +1,17 @@
class AddCreatedAtToAllTables < ActiveRecord::Migration
- def self.up
- ActiveRecord::Base.connection.tables.each do |t|
- unless ActiveRecord::Base.connection.columns(t).collect {|c| c.name}.include?("created_at")
- add_column t.to_s, :created_at, :datetime
- end
- end
- end
+ def self.up
+ ActiveRecord::Base.connection.tables.each do |t|
+ unless ActiveRecord::Base.connection.columns(t).collect {|c| c.name}.include?("created_at")
+ add_column t.to_s, :created_at, :datetime
+ end
+ end
+ end
- def self.down
- ActiveRecord::Base.connection.tables.each do |t|
- unless ActiveRecord::Base.connection.columns(t).collect {|c| c.name}.include?("created_at")
- remove_column t.to_s, :created_at
- end
- end
- end
+ def self.down
+ ActiveRecord::Base.connection.tables.each do |t|
+ unless ActiveRecord::Base.connection.columns(t).collect {|c| c.name}.include?("created_at")
+ remove_column t.to_s, :created_at
+ end
+ end
+ end
end
diff --git a/lib/puppet/sslcertificates/ca.rb b/lib/puppet/sslcertificates/ca.rb
index 7386318f4..2a16a32ba 100644
--- a/lib/puppet/sslcertificates/ca.rb
+++ b/lib/puppet/sslcertificates/ca.rb
@@ -97,7 +97,7 @@ class Puppet::SSLCertificates::CA
if @config[:capass] and File.readable?(@config[:capass])
return File.read(@config[:capass])
else
- raise Puppet::Error, "Could not read CA passfile %s" % @config[:capass]
+ raise Puppet::Error, "Could not decrypt CA key with password: %s" % detail
end
end
@@ -379,9 +379,14 @@ class Puppet::SSLCertificates::CA
def sign_with_key(signable, digest = OpenSSL::Digest::SHA1.new)
cakey = nil
if @config[:password]
- cakey = OpenSSL::PKey::RSA.new(
- File.read(@config[:cakey]), @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])
diff --git a/lib/puppet/util/resource_template.rb b/lib/puppet/util/resource_template.rb
new file mode 100644
index 000000000..53066a192
--- /dev/null
+++ b/lib/puppet/util/resource_template.rb
@@ -0,0 +1,61 @@
+require 'puppet/util'
+require 'puppet/util/logging'
+require 'erb'
+
+# A template wrapper that evaluates a template in the
+# context of a resource, allowing the resource attributes
+# to be looked up from within the template.
+# This provides functionality essentially equivalent to
+# the language's template() function. You pass your file
+# path and the resource you want to use into the initialization
+# method, then call result() on the instance, and you get back
+# a chunk of text.
+# The resource's parameters are available as instance variables
+# (as opposed to the language, where we use a method_missing trick).
+# For example, say you have a resource that generates a file. You would
+# need to implement the following style of `generate` method:
+#
+# def generate
+# template = Puppet::Util::ResourceTemplate.new("/path/to/template", self)
+#
+# return Puppet::Type.type(:file).create :path => "/my/file",
+# :content => template.evaluate
+# end
+#
+# This generated file gets added to the catalog (which is what `generate` does),
+# and its content is the result of the template. You need to use instance
+# variables in your template, so if your template just needs to have the name
+# of the generating resource, it would just have:
+#
+# <%= @name %>
+#
+# Since the ResourceTemplate class sets as instance variables all of the resource's
+# parameters.
+#
+# Note that this example uses the generating resource as its source of
+# 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
+
+ def evaluate
+ set_resource_variables
+ ERB.new(File.read(@file), 0, "-").result(binding)
+ end
+
+ def initialize(file, resource)
+ raise ArgumentError, "Template %s does not exist" % file unless FileTest.exist?(file)
+ @file = file
+ @resource = resource
+ end
+
+ private
+
+ 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/spec/integration/indirector/rest.rb b/spec/integration/indirector/rest.rb
index 859648f7d..584fedde0 100755
--- a/spec/integration/indirector/rest.rb
+++ b/spec/integration/indirector/rest.rb
@@ -29,8 +29,6 @@ end
class Puppet::TestIndirectedFoo::Rest < Puppet::Indirector::REST
end
-# This way the retrieval of the class by name works.
-Puppet::Indirector::Terminus.register_terminus_class(Puppet::TestIndirectedFoo::Rest)
describe Puppet::Indirector::REST do
before do
@@ -65,18 +63,11 @@ describe Puppet::Indirector::REST do
ca = Puppet::SSL::CertificateAuthority.new
ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
-
+
@params = { :address => "127.0.0.1", :port => 34343, :handlers => [ :test_indirected_foo ], :xmlrpc_handlers => [ :status ] }
@server = Puppet::Network::Server.new(@params)
@server.listen
end
-
- after do
- @server.unlisten
- @tmpfile.delete
- Puppet.settings.clear
- Puppet::Util::Cacher.invalidate
- end
describe "when finding a model instance over REST" do
describe "when a matching model instance can be found" do
@@ -87,7 +78,6 @@ describe Puppet::Indirector::REST do
end
it "should not fail" do
- Puppet::TestIndirectedFoo.find('bar')
lambda { Puppet::TestIndirectedFoo.find('bar') }.should_not raise_error
end
@@ -151,7 +141,15 @@ describe Puppet::Indirector::REST do
end
it 'should return the instance of the model class associated with the provided lookup key' do
- Puppet::TestIndirectedFoo.search('bar').collect{ |x| x.value }.should == @model_instances.collect{ |x| x.value }
+ Puppet::TestIndirectedFoo.search('bar').collect { |i| i.value }.should == @model_instances.collect { |i| i.value }
+ end
+
+ it 'should set a version timestamp on model instances' do
+ pending("Luke looking at why this version magic might not be working") do
+ Puppet::TestIndirectedFoo.search('bar').each do |result|
+ result.version.should_not be_nil
+ end
+ end
end
end
@@ -264,6 +262,10 @@ describe Puppet::Indirector::REST do
end
end
end
+
+ after :each do
+ @server.unlisten
+ end
end
describe "when using mongrel" do
@@ -283,7 +285,7 @@ describe Puppet::Indirector::REST do
@server.listen
end
- after :each do
+ after do
@server.unlisten
end
@@ -359,7 +361,7 @@ describe Puppet::Indirector::REST do
end
it 'should return the instance of the model class associated with the provided lookup key' do
- Puppet::TestIndirectedFoo.search('bar').collect{ |x| x.value }.should == @model_instances.collect{ |x| x.value }
+ 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
@@ -438,6 +440,9 @@ describe Puppet::Indirector::REST do
@instance = Puppet::TestIndirectedFoo.new(42)
@mock_model = stub('faked model', :from_yaml => @instance)
Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)
+
+ # 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
diff --git a/spec/integration/network/server/mongrel.rb b/spec/integration/network/server/mongrel.rb
index 08fd49b17..180fdf7ad 100755
--- a/spec/integration/network/server/mongrel.rb
+++ b/spec/integration/network/server/mongrel.rb
@@ -1,46 +1,48 @@
+#!/usr/bin/env ruby
+
require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/network/server'
require 'socket'
describe Puppet::Network::Server do
- describe "when using mongrel" do
- confine "Mongrel is not available" => Puppet.features.mongrel?
-
- before :each do
- Puppet[:servertype] = 'mongrel'
- @params = { :address => "127.0.0.1", :port => 34346, :handlers => [ :node ], :xmlrpc_handlers => [ :status ] }
- @server = Puppet::Network::Server.new(@params)
- end
+ describe "when using mongrel" do
+ confine "Mongrel is not available" => Puppet.features.mongrel?
+
+ before :each do
+ Puppet[:servertype] = 'mongrel'
+ @params = { :address => "127.0.0.1", :port => 34346, :handlers => [ :node ] }
+ @server = Puppet::Network::Server.new(@params)
+ 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 "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 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
+ 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
+
+ after :each do
+ @server.unlisten if @server.listening?
+ end
end
-
- after :each do
- @server.unlisten if @server.listening?
- end
- end
end
diff --git a/spec/integration/network/server/webrick.rb b/spec/integration/network/server/webrick.rb
index 0e66ee955..e74920782 100755
--- a/spec/integration/network/server/webrick.rb
+++ b/spec/integration/network/server/webrick.rb
@@ -41,13 +41,13 @@ describe Puppet::Network::Server do
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 = Puppet::Network::Server.new(@params.merge(:port => 34343))
@server.listen
- lambda { TCPSocket.new('127.0.0.1', 34343) }.should_not raise_error
+ lambda { TCPSocket.new('127.0.0.1', 34343) }.should_not raise_error
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 = 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
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 e2f3d4728..0b4a5abdb 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,35 +9,35 @@ require 'puppettest'
require 'puppettest/runnable_test'
module Spec
- module Runner
- class ExampleGroupRunner
- def run
- prepare
- success = true
- example_groups.each do |example_group|
- next unless example_group.runnable?
- success = success & example_group.run
+ module Runner
+ class ExampleGroupRunner
+ def run
+ prepare
+ success = true
+ example_groups.each do |example_group|
+ next unless example_group.runnable?
+ success = success & example_group.run
+ end
+ return success
+ ensure
+ finish
+ end
end
- return success
- ensure
- finish
- end
end
- end
end
module Spec
- module Example
- class ExampleGroup
- extend PuppetTest::RunnableTest
+ module Example
+ class ExampleGroup
+ extend PuppetTest::RunnableTest
+ end
end
- end
end
module Test
- module Unit
- class TestCase
- extend PuppetTest::RunnableTest
+ module Unit
+ class TestCase
+ extend PuppetTest::RunnableTest
+ end
end
- end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index a1999a333..52aed5b62 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -23,7 +23,7 @@ require 'spec'
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
diff --git a/spec/unit/executables/client/certhandler.rb b/spec/unit/executables/client/certhandler.rb
new file mode 100755
index 000000000..3737c9a57
--- /dev/null
+++ b/spec/unit/executables/client/certhandler.rb
@@ -0,0 +1,88 @@
+#!/usr/bin/env ruby
+
+Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
+
+require 'puppet/executables/client/certhandler'
+
+cert_handler = Puppet::Executables::Client::CertHandler
+
+describe cert_handler, "when handling certificates" do
+ before do
+ @caclient = mock('caclient')
+ caclient_class = mock('caclient_class')
+ caclient_class.stubs(:new).returns(@caclient)
+ Puppet::Network::Client.stubs(:ca).returns(caclient_class)
+ end
+
+ it "should return true if the certificate exists" do
+ @caclient.expects(:read_cert).returns(true)
+ cert_handler.new(1,true).read_retrieve.should be_true
+ end
+
+ it "should return false when getting a new cert" do
+ @caclient.expects(:read_cert).returns(true)
+ @caclient.stubs(:request_cert).returns(true)
+ ch = cert_handler.new(1,true)
+ ch.stubs(:read_cert).returns(false)
+ ch.read_retrieve.should be_false
+ end
+
+ describe "when waiting for cert" do
+ before do
+ @caclient.stubs(:read_cert).returns false
+ end
+
+ it "should loop when the cert request does not return a certificate" do
+ @caclient.stubs(:request_cert).times(2).returns(false).then.returns(true)
+ ch = cert_handler.new(1,false)
+ ch.expects(:sleep)
+ ch.expects(:read_new_cert).returns(true)
+ ch.read_retrieve
+ end
+
+ it "should loop when the cert request raises an Error" do
+ @caclient.stubs(:request_cert).times(2).raises(StandardError, 'Testing').then.returns(true)
+ ch = cert_handler.new(1,false)
+ ch.expects(:sleep)
+ ch.expects(:read_new_cert).returns(true)
+ ch.read_retrieve
+ end
+
+ it "should loop when the new cert can't be read" do
+ @caclient.stubs(:request_cert).returns(true)
+ ch = cert_handler.new(1,false)
+ ch.expects(:sleep)
+ ch.expects(:read_new_cert).times(2).returns(false).then.returns(true)
+ ch.read_retrieve
+ end
+ end
+
+ describe "when in one time mode" do
+ before do
+ @caclient.stubs(:read_cert).returns false
+ end
+
+ it "should exit if the cert request does not return a certificate" do
+ @caclient.stubs(:request_cert).returns(false)
+ ch = cert_handler.new(1,true)
+ ch.expects(:exit).with(1).raises(SystemExit)
+ lambda { ch.read_retrieve }.should raise_error(SystemExit)
+ end
+
+
+ it "should exit if the cert request raises an exception" do
+ @caclient.stubs(:request_cert).raises(StandardError, 'Testing')
+ ch = cert_handler.new(1,true)
+ ch.expects(:exit).with(23).raises(SystemExit)
+ lambda { ch.read_retrieve }.should raise_error(SystemExit)
+ end
+
+ it "should exit if the new cert can't be read" do
+ @caclient.stubs(:request_cert).returns(true)
+ @caclient.stubs(:read_cert).returns(false)
+ ch = cert_handler.new(1,true)
+ ch.expects(:exit).with(34).raises(SystemExit)
+ lambda { ch.read_retrieve }.should raise_error(SystemExit)
+ end
+ end
+end
diff --git a/spec/unit/indirector/indirection.rb b/spec/unit/indirector/indirection.rb
index e4799d3ff..e52be31e1 100755
--- a/spec/unit/indirector/indirection.rb
+++ b/spec/unit/indirector/indirection.rb
@@ -6,7 +6,7 @@ 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 = stub 'request', :options => {}
+ request = stub 'request', :node => nil
@indirection.expects(:request).with(@method, "mystuff", :one => :two).returns request
@@ -342,7 +342,7 @@ describe Puppet::Indirector::Indirection do
end
it "should use a request to save the object to the cache" do
- request = stub 'request', :instance => @instance, :options => {}
+ request = stub 'request', :instance => @instance, :node => nil
@indirection.expects(:request).returns request
@@ -373,8 +373,8 @@ describe Puppet::Indirector::Indirection do
end
it "should use a request instance to search in and remove objects from the cache" do
- destroy = stub 'destroy_request', :key => "/my/key", :options => {}
- find = stub 'destroy_request', :key => "/my/key", :options => {}
+ 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
diff --git a/spec/unit/indirector/module_files.rb b/spec/unit/indirector/module_files.rb
index 0f6dbb6df..f5b92e1fd 100755
--- a/spec/unit/indirector/module_files.rb
+++ b/spec/unit/indirector/module_files.rb
@@ -10,24 +10,24 @@ require 'puppet/indirector/module_files'
describe Puppet::Indirector::ModuleFiles do
- before :each do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- 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)
-
- @module_files_class = Class.new(Puppet::Indirector::ModuleFiles) do
- def self.to_s
- "Testing::Mytype"
- end
- end
-
- @module_files = @module_files_class.new
-
- @uri = "puppetmounts://host/modules/my/local/file"
- @module = Puppet::Module.new("mymod", "/module/path")
- end
+ before :each do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ 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)
+
+ @module_files_class = Class.new(Puppet::Indirector::ModuleFiles) do
+ def self.to_s
+ "Testing::Mytype"
+ end
+ end
+
+ @module_files = @module_files_class.new
+
+ @uri = "puppetmounts://host/modules/my/local/file"
+ @module = Puppet::Module.new("mymod", "/module/path")
+ end
describe Puppet::Indirector::ModuleFiles, " when finding files" do
diff --git a/spec/unit/indirector/request.rb b/spec/unit/indirector/request.rb
index cdb40b181..f7702f821 100755
--- a/spec/unit/indirector/request.rb
+++ b/spec/unit/indirector/request.rb
@@ -43,6 +43,38 @@ describe Puppet::Indirector::Request do
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 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 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 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 another option is specified" do
+ Puppet::Indirector::Request.new(:ind, :method, :key, :foo => "bar").options.should be_instance_of(Hash)
+ end
end
it "should look use the Indirection class to return the appropriate indirection" do
diff --git a/spec/unit/network/client.rb b/spec/unit/network/client.rb
index e9467aad0..e9467aad0 100644..100755
--- a/spec/unit/network/client.rb
+++ b/spec/unit/network/client.rb
diff --git a/spec/unit/network/http.rb b/spec/unit/network/http.rb
index 79a0a88d4..79a0a88d4 100644..100755
--- a/spec/unit/network/http.rb
+++ b/spec/unit/network/http.rb
diff --git a/spec/unit/network/http/mongrel.rb b/spec/unit/network/http/mongrel.rb
index 1f87fd943..1f87fd943 100644..100755
--- a/spec/unit/network/http/mongrel.rb
+++ b/spec/unit/network/http/mongrel.rb
diff --git a/spec/unit/network/http/mongrel/rest.rb b/spec/unit/network/http/mongrel/rest.rb
index b483bbd46..3df925133 100644..100755
--- a/spec/unit/network/http/mongrel/rest.rb
+++ b/spec/unit/network/http/mongrel/rest.rb
@@ -1,9 +1,11 @@
+#!/usr/bin/env ruby
+
require File.dirname(__FILE__) + '/../../../../spec_helper'
require 'puppet/network/http'
describe Puppet::Network::HTTP::MongrelREST, "when initializing" do
confine "Mongrel is not available" => Puppet.features.mongrel?
-
+
before do
@mock_mongrel = mock('Mongrel server')
@mock_mongrel.stubs(:register)
@@ -11,20 +13,20 @@ describe Puppet::Network::HTTP::MongrelREST, "when initializing" do
Puppet::Indirector::Indirection.stubs(:model).with(:foo).returns(@mock_model)
@params = { :server => @mock_mongrel, :handler => :foo }
end
-
+
it "should require access to a Mongrel server" do
Proc.new { Puppet::Network::HTTP::MongrelREST.new(@params.delete_if {|k,v| :server == k })}.should raise_error(ArgumentError)
end
-
+
it "should require an indirection name" do
Proc.new { Puppet::Network::HTTP::MongrelREST.new(@params.delete_if {|k,v| :handler == k })}.should raise_error(ArgumentError)
end
-
+
it "should look up the indirection model from the indirection name" do
Puppet::Indirector::Indirection.expects(:model).with(:foo).returns(@mock_model)
Puppet::Network::HTTP::MongrelREST.new(@params)
end
-
+
it "should fail if the indirection is not known" do
Puppet::Indirector::Indirection.expects(:model).with(:foo).returns(nil)
Proc.new { Puppet::Network::HTTP::MongrelREST.new(@params) }.should raise_error(ArgumentError)
@@ -33,7 +35,7 @@ end
describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do
confine "Mongrel is not available" => Puppet.features.mongrel?
-
+
before do
@mock_request = stub('mongrel http request')
@mock_head = stub('response head')
@@ -45,28 +47,28 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do
Puppet::Indirector::Indirection.stubs(:model).with(:foo).returns(@mock_model_class)
@handler = Puppet::Network::HTTP::MongrelREST.new(:server => @mock_mongrel, :handler => :foo)
end
-
+
def setup_find_request(params = {})
@mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET',
Mongrel::Const::REQUEST_PATH => '/foo/key',
'QUERY_STRING' => ''}.merge(params))
@mock_model_class.stubs(:find)
end
-
+
def setup_search_request(params = {})
@mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET',
Mongrel::Const::REQUEST_PATH => '/foos',
'QUERY_STRING' => '' }.merge(params))
@mock_model_class.stubs(:search).returns([])
end
-
+
def setup_destroy_request(params = {})
@mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'DELETE',
Mongrel::Const::REQUEST_PATH => '/foo/key',
'QUERY_STRING' => '' }.merge(params))
@mock_model_class.stubs(:destroy)
end
-
+
def setup_save_request(params = {})
@mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'PUT',
Mongrel::Const::REQUEST_PATH => '/foo',
@@ -75,26 +77,26 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do
@mock_model_instance = stub('indirected model instance', :save => true)
@mock_model_class.stubs(:from_yaml).returns(@mock_model_instance)
end
-
+
def setup_bad_request
@mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'POST', Mongrel::Const::REQUEST_PATH => '/foos'})
end
it "should call the model find method if the request represents a singular HTTP GET" do
setup_find_request
- @mock_model_class.expects(:find).with('key', {})
+ @mock_model_class.expects(:find).with { |key, args| key == 'key' }
@handler.process(@mock_request, @mock_response)
end
it "should call the model search method if the request represents a plural HTTP GET" do
setup_search_request
- @mock_model_class.expects(:search).with({}).returns([])
+ @mock_model_class.expects(:search).returns([])
@handler.process(@mock_request, @mock_response)
end
-
+
it "should call the model destroy method if the request represents an HTTP DELETE" do
setup_destroy_request
- @mock_model_class.expects(:destroy).with('key', {})
+ @mock_model_class.expects(:destroy).with { |key, args| key == 'key' }
@handler.process(@mock_request, @mock_response)
end
@@ -103,13 +105,13 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do
@mock_model_instance.expects(:save)
@handler.process(@mock_request, @mock_response)
end
-
+
it "should fail if the HTTP method isn't supported" do
@mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'POST', Mongrel::Const::REQUEST_PATH => '/foo'})
@mock_response.expects(:start).with(404)
@handler.process(@mock_request, @mock_response)
end
-
+
it "should fail if the request's pluralization is wrong" do
@mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'DELETE', Mongrel::Const::REQUEST_PATH => '/foos/key'})
@mock_response.expects(:start).with(404)
@@ -127,8 +129,74 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do
@mock_response.expects(:start).with(404)
@handler.process(@mock_request, @mock_response)
end
-
-
+
+ describe "and determining the request parameters", :shared => true do
+ before do
+ @mock_request.stubs(:params).returns({})
+ end
+
+ it "should include the HTTP request parameters" do
+ @mock_request.expects(:params).returns('QUERY_STRING' => 'foo=baz&bar=xyzzy')
+ result = @handler.params(@mock_request)
+ result["foo"].should == "baz"
+ result["bar"].should == "xyzzy"
+ end
+
+ it "should pass the client's ip address to model find" do
+ @mock_request.stubs(:params).returns("REMOTE_ADDR" => "ipaddress")
+ @handler.params(@mock_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"
+ @mock_request.stubs(:params).returns("myheader" => "/CN=host.domain.com")
+ @handler.params(@mock_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"
+ @mock_request.stubs(:params).returns("myheader" => "/CN=host.domain.com")
+ @handler.params(@mock_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"
+ @mock_request.stubs(:params).returns("myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com")
+ @handler.params(@mock_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"
+ @mock_request.stubs(:params).returns("myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com")
+ @handler.params(@mock_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"
+ @mock_request.stubs(:params).returns("myheader" => "whatever", "certheader" => "/CN=host.domain.com")
+ @handler.params(@mock_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"
+ @mock_request.stubs(:params).returns("myheader" => nil, "certheader" => "SUCCESS")
+ @handler.params(@mock_request)[:authenticated].should be_false
+ end
+
+ it "should not pass a node name to model method if no certificate information is present" do
+ Puppet.settings.stubs(:value).returns "eh"
+ Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
+ @mock_request.stubs(:params).returns("myheader" => nil)
+ @handler.params(@mock_request).should_not be_include(:node)
+ end
+ end
+
describe "when finding a model instance" do |variable|
it "should fail to find model if key is not specified" do
@mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET', Mongrel::Const::REQUEST_PATH => '/foo'})
@@ -136,20 +204,21 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do
@handler.process(@mock_request, @mock_response)
end
- it "should pass HTTP request parameters to model find" do
+ it "should use a common method for determining the request parameters" do
setup_find_request('QUERY_STRING' => 'foo=baz&bar=xyzzy')
+ @handler.expects(:params).returns(:foo => :baz, :bar => :xyzzy)
@mock_model_class.expects(:find).with do |key, args|
- key == 'key' and args['foo'] == 'baz' and args['bar'] == 'xyzzy'
+ args[:foo] == :baz and args[:bar] == :xyzzy
end
@handler.process(@mock_request, @mock_response)
end
-
+
it "should generate a 200 response when a model find call succeeds" do
setup_find_request
@mock_response.expects(:start).with(200)
@handler.process(@mock_request, @mock_response)
end
-
+
it "should return a serialized object when a model find call succeeds" do
setup_find_request
@mock_model_instance = stub('model instance')
@@ -157,7 +226,7 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do
@mock_model_class.stubs(:find).returns(@mock_model_instance)
@handler.process(@mock_request, @mock_response)
end
-
+
it "should serialize a controller exception when an exception is thrown by find" do
setup_find_request
@mock_model_class.expects(:find).raises(ArgumentError)
@@ -172,7 +241,16 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do
@mock_response.expects(:start).with(404)
@handler.process(@mock_request, @mock_response)
end
-
+
+ it "should use a common method for determining the request parameters" do
+ setup_destroy_request('QUERY_STRING' => 'foo=baz&bar=xyzzy')
+ @handler.expects(:params).returns(:foo => :baz, :bar => :xyzzy)
+ @mock_model_class.expects(:destroy).with do |key, args|
+ args[:foo] == :baz and args[:bar] == :xyzzy
+ end
+ @handler.process(@mock_request, @mock_response)
+ end
+
it "should pass HTTP request parameters to model destroy" do
setup_destroy_request('QUERY_STRING' => 'foo=baz&bar=xyzzy')
@mock_model_class.expects(:destroy).with do |key, args|
@@ -180,20 +258,20 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do
end
@handler.process(@mock_request, @mock_response)
end
-
+
it "should generate a 200 response when a model destroy call succeeds" do
setup_destroy_request
@mock_response.expects(:start).with(200)
@handler.process(@mock_request, @mock_response)
end
-
+
it "should return a serialized success result when a model destroy call succeeds" do
setup_destroy_request
@mock_model_class.stubs(:destroy).returns(true)
@mock_body.expects(:write).with("--- true\n")
@handler.process(@mock_request, @mock_response)
end
-
+
it "should serialize a controller exception when an exception is thrown by destroy" do
setup_destroy_request
@mock_model_class.expects(:destroy).raises(ArgumentError)
@@ -201,7 +279,7 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do
@handler.process(@mock_request, @mock_response)
end
end
-
+
describe "when saving a model instance" do |variable|
it "should fail to save model if data is not specified" do
@mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'PUT', Mongrel::Const::REQUEST_PATH => '/foo'})
@@ -209,20 +287,29 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do
@mock_response.expects(:start).with(404)
@handler.process(@mock_request, @mock_response)
end
-
+
+ it "should use a common method for determining the request parameters" do
+ setup_save_request('QUERY_STRING' => 'foo=baz&bar=xyzzy')
+ @handler.expects(:params).returns(:foo => :baz, :bar => :xyzzy)
+ @mock_model_instance.expects(:save).with do |args|
+ args[:foo] == :baz and args[:bar] == :xyzzy
+ end
+ @handler.process(@mock_request, @mock_response)
+ end
+
it "should generate a 200 response when a model save call succeeds" do
setup_save_request
@mock_response.expects(:start).with(200)
@handler.process(@mock_request, @mock_response)
end
-
+
it "should return a serialized object when a model save call succeeds" do
setup_save_request
@mock_model_instance.stubs(:save).returns(@mock_model_instance)
@mock_model_instance.expects(:to_yaml).returns('foo')
@handler.process(@mock_request, @mock_response)
end
-
+
it "should serialize a controller exception when an exception is thrown by save" do
setup_save_request
@mock_model_instance.expects(:save).raises(ArgumentError)
@@ -230,8 +317,17 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do
@handler.process(@mock_request, @mock_response)
end
end
-
+
describe "when searching for model instances" do |variable|
+ it "should use a common method for determining the request parameters" do
+ setup_search_request('QUERY_STRING' => 'foo=baz&bar=xyzzy')
+ @handler.expects(:params).returns(:foo => :baz, :bar => :xyzzy)
+ @mock_model_class.expects(:search).with do |args|
+ args[:foo] == :baz and args[:bar] == :xyzzy
+ end
+ @handler.process(@mock_request, @mock_response)
+ end
+
it "should pass HTTP request parameters to model search" do
setup_search_request('QUERY_STRING' => 'foo=baz&bar=xyzzy')
@mock_model_class.expects(:search).with do |args|
@@ -245,7 +341,7 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do
@mock_response.expects(:start).with(200)
@handler.process(@mock_request, @mock_response)
end
-
+
it "should return a list of serialized objects when a model search call succeeds" do
setup_search_request
mock_matches = [1..5].collect {|i| mock("model instance #{i}", :to_yaml => "model instance #{i}") }
@@ -260,7 +356,7 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do
@handler.process(@mock_request, @mock_response)
end
end
-
+
it "should serialize a controller exception if the request fails" do
setup_bad_request
@mock_response.expects(:start).with(404)
diff --git a/spec/unit/network/http/mongrel/xmlrpc.rb b/spec/unit/network/http/mongrel/xmlrpc.rb
index e69de29bb..e69de29bb 100644..100755
--- a/spec/unit/network/http/mongrel/xmlrpc.rb
+++ b/spec/unit/network/http/mongrel/xmlrpc.rb
diff --git a/spec/unit/network/http/webrick.rb b/spec/unit/network/http/webrick.rb
index 6d006992c..e3c3b81c0 100644..100755
--- a/spec/unit/network/http/webrick.rb
+++ b/spec/unit/network/http/webrick.rb
@@ -162,7 +162,7 @@ describe Puppet::Network::HTTP::WEBrick, "when looking up the class to handle a
end
it "should accept a protocol" do
- lambda { Puppet::Network::HTTP::WEBrick.class_for_protocol("bob") }.should_not raise_error(ArgumentError)
+ 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
diff --git a/spec/unit/network/http/webrick/rest.rb b/spec/unit/network/http/webrick/rest.rb
index b7bd33880..45e5f0bd2 100644..100755
--- a/spec/unit/network/http/webrick/rest.rb
+++ b/spec/unit/network/http/webrick/rest.rb
@@ -1,3 +1,5 @@
+#!/usr/bin/env ruby
+
require File.dirname(__FILE__) + '/../../../../spec_helper'
require 'puppet/network/http'
@@ -8,23 +10,23 @@ describe Puppet::Network::HTTP::WEBrickREST, "when initializing" do
Puppet::Indirector::Indirection.stubs(:model).returns(@mock_model)
@params = [ @mock_webrick, :foo ]
end
-
+
it "should require access to a WEBrick server" do
Proc.new {
@params[0] = nil
Puppet::Network::HTTP::WEBrickREST.new(*@params)
}.should raise_error(ArgumentError)
end
-
+
it "should require an indirection name" do
Proc.new { Puppet::Network::HTTP::WEBrickREST.new(@params.first) }.should raise_error(ArgumentError)
end
-
+
it "should look up the indirection model from the indirection name" do
Puppet::Indirector::Indirection.expects(:model).returns(@mock_model)
Puppet::Network::HTTP::WEBrickREST.new(*@params)
end
-
+
it "should fail if the indirection is not known" do
Puppet::Indirector::Indirection.expects(:model).returns(nil)
Proc.new { Puppet::Network::HTTP::WEBrickREST.new(*@params) }.should raise_error(ArgumentError)
@@ -33,7 +35,7 @@ end
describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do
before do
- @mock_request = stub('webrick http request', :query => {})
+ @mock_request = stub('webrick http request', :query => {}, :peeraddr => %w{eh boo host ip}, :client_cert => nil)
@mock_response = stub('webrick http response', :status= => true, :body= => true)
@mock_model_class = stub('indirected model class')
@mock_webrick = stub('webrick http server', :mount => true, :[] => {})
@@ -46,19 +48,19 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do
@mock_request.stubs(:path).returns('/foo/key')
@mock_model_class.stubs(:find)
end
-
+
def setup_search_request
@mock_request.stubs(:request_method).returns('GET')
@mock_request.stubs(:path).returns('/foos')
@mock_model_class.stubs(:search).returns([])
end
-
+
def setup_destroy_request
@mock_request.stubs(:request_method).returns('DELETE')
@mock_request.stubs(:path).returns('/foo/key')
@mock_model_class.stubs(:destroy)
end
-
+
def setup_save_request
@mock_request.stubs(:request_method).returns('PUT')
@mock_request.stubs(:path).returns('/foo')
@@ -66,44 +68,48 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do
@mock_model_instance = stub('indirected model instance', :save => true)
@mock_model_class.stubs(:from_yaml).returns(@mock_model_instance)
end
-
+
def setup_bad_request
@mock_request.stubs(:request_method).returns('POST')
@mock_request.stubs(:path).returns('/foos')
end
-
-
+
+ it "should delegate its :service method to its :process method" do
+ @handler.expects(:process).with(@mock_request, @mock_response).returns "stuff"
+ @handler.service(@mock_request, @mock_response).should == "stuff"
+ end
+
it "should call the model find method if the request represents a singular HTTP GET" do
setup_find_request
- @mock_model_class.expects(:find).with('key', {})
- @handler.service(@mock_request, @mock_response)
+ @mock_model_class.expects(:find).with { |key, args| key == 'key' }
+ @handler.process(@mock_request, @mock_response)
end
it "should call the model search method if the request represents a plural HTTP GET" do
setup_search_request
@mock_model_class.expects(:search).returns([])
- @handler.service(@mock_request, @mock_response)
+ @handler.process(@mock_request, @mock_response)
end
-
+
it "should call the model destroy method if the request represents an HTTP DELETE" do
setup_destroy_request
- @mock_model_class.expects(:destroy).with('key', {})
- @handler.service(@mock_request, @mock_response)
+ @mock_model_class.expects(:destroy).with { |key, args| key == 'key' }
+ @handler.process(@mock_request, @mock_response)
end
it "should call the model save method if the request represents an HTTP PUT" do
setup_save_request
@mock_model_instance.expects(:save)
- @handler.service(@mock_request, @mock_response)
+ @handler.process(@mock_request, @mock_response)
end
-
+
it "should fail if the HTTP method isn't supported" do
@mock_request.stubs(:request_method).returns('POST')
@mock_request.stubs(:path).returns('/foo')
@mock_response.expects(:status=).with(404)
@handler.process(@mock_request, @mock_response)
end
-
+
it "should fail if delete request's pluralization is wrong" do
@mock_request.stubs(:request_method).returns('DELETE')
@mock_request.stubs(:path).returns('/foos/key')
@@ -125,6 +131,42 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do
@handler.process(@mock_request, @mock_response)
end
+ describe "and determining the request parameters" do
+ it "should include the HTTP request parameters" do
+ @mock_request.stubs(:query).returns(:foo => :baz, :bar => :xyzzy)
+ result = @handler.params(@mock_request)
+ result[:foo].should == :baz
+ result[:bar].should == :xyzzy
+ end
+
+ it "should pass the client's ip address to model find" do
+ @mock_request.stubs(:peeraddr).returns(%w{noidea dunno hostname ipaddress})
+ @handler.params(@mock_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}]
+ @mock_request.stubs(:client_cert).returns cert
+ @handler.params(@mock_request)[:authenticated].should be_true
+ end
+
+ it "should set 'authenticated' to false if no certificate is present" do
+ @mock_request.stubs(:client_cert).returns nil
+ @handler.params(@mock_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}]
+ @mock_request.stubs(:client_cert).returns cert
+ @handler.params(@mock_request)[:node].should == "host.domain.com"
+ end
+
+ it "should not pass a node name to model method if no certificate is present" do
+ @mock_request.stubs(:client_cert).returns nil
+ @handler.params(@mock_request).should_not be_include(:node)
+ end
+ end
+
describe "when finding a model instance" do |variable|
it "should fail to find model if key is not specified" do
@mock_request.stubs(:request_method).returns('GET')
@@ -132,22 +174,22 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do
@mock_response.expects(:status=).with(404)
@handler.process(@mock_request, @mock_response)
end
-
- it "should pass HTTP request parameters to model find" do
+
+ it "should use a common method for determining the request parameters" do
setup_find_request
- @mock_request.stubs(:query).returns(:foo => :baz, :bar => :xyzzy)
+ @handler.stubs(:params).returns(:foo => :baz, :bar => :xyzzy)
@mock_model_class.expects(:find).with do |key, args|
- key == 'key' and args[:foo] == :baz and args[:bar] == :xyzzy
+ args[:foo] == :baz and args[:bar] == :xyzzy
end
- @handler.service(@mock_request, @mock_response)
+ @handler.process(@mock_request, @mock_response)
end
-
+
it "should generate a 200 response when a model find call succeeds" do
setup_find_request
@mock_response.expects(:status=).with(200)
@handler.process(@mock_request, @mock_response)
end
-
+
it "should return a serialized object when a model find call succeeds" do
setup_find_request
@mock_model_instance = stub('model instance')
@@ -155,7 +197,7 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do
@mock_model_class.stubs(:find).returns(@mock_model_instance)
@handler.process(@mock_request, @mock_response)
end
-
+
it "should serialize a controller exception when an exception is thrown by find" do
setup_find_request
@mock_model_class.expects(:find).raises(ArgumentError)
@@ -163,7 +205,7 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do
@handler.process(@mock_request, @mock_response)
end
end
-
+
describe "when destroying a model instance" do |variable|
it "should fail to destroy model if key is not specified" do
@mock_request.stubs(:request_method).returns('DELETE')
@@ -171,37 +213,37 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do
@mock_response.expects(:status=).with(404)
@handler.process(@mock_request, @mock_response)
end
-
- it "should pass HTTP request parameters to model destroy" do
+
+ it "should use a common method for determining the request parameters" do
setup_destroy_request
- @mock_request.stubs(:query).returns(:foo => :baz, :bar => :xyzzy)
+ @handler.stubs(:params).returns(:foo => :baz, :bar => :xyzzy)
@mock_model_class.expects(:destroy).with do |key, args|
- key == 'key' and args[:foo] == :baz and args[:bar] == :xyzzy
+ args[:foo] == :baz and args[:bar] == :xyzzy
end
- @handler.service(@mock_request, @mock_response)
+ @handler.process(@mock_request, @mock_response)
end
-
+
it "should generate a 200 response when a model destroy call succeeds" do
setup_destroy_request
@mock_response.expects(:status=).with(200)
@handler.process(@mock_request, @mock_response)
end
-
+
it "should return a serialized success result when a model destroy call succeeds" do
setup_destroy_request
@mock_model_class.stubs(:destroy).returns(true)
@mock_response.expects(:body=).with("--- true\n")
@handler.process(@mock_request, @mock_response)
end
-
- it "should serialize a controller exception when an exception is thrown by search" do
- setup_search_request
- @mock_model_class.expects(:search).raises(ArgumentError)
+
+ it "should serialize a controller exception when an exception is thrown by destroy" do
+ setup_destroy_request
+ @mock_model_class.expects(:destroy).raises(ArgumentError)
@mock_response.expects(:status=).with(404)
- @handler.process(@mock_request, @mock_response)
- end
+ @handler.process(@mock_request, @mock_response)
+ end
end
-
+
describe "when saving a model instance" do
it "should fail to save model if data is not specified" do
@mock_request.stubs(:request_method).returns('PUT')
@@ -210,20 +252,29 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do
@mock_response.expects(:status=).with(404)
@handler.process(@mock_request, @mock_response)
end
-
+
+ it "should use a common method for determining the request parameters" do
+ setup_save_request
+ @handler.stubs(:params).returns(:foo => :baz, :bar => :xyzzy)
+ @mock_model_instance.expects(:save).with do |args|
+ args[:foo] == :baz and args[:bar] == :xyzzy
+ end
+ @handler.process(@mock_request, @mock_response)
+ end
+
it "should generate a 200 response when a model save call succeeds" do
setup_save_request
@mock_response.expects(:status=).with(200)
@handler.process(@mock_request, @mock_response)
end
-
+
it "should return a serialized object when a model save call succeeds" do
setup_save_request
@mock_model_instance.stubs(:save).returns(@mock_model_instance)
@mock_model_instance.expects(:to_yaml).returns('foo')
@handler.process(@mock_request, @mock_response)
end
-
+
it "should serialize a controller exception when an exception is thrown by save" do
setup_save_request
@mock_model_instance.expects(:save).raises(ArgumentError)
@@ -231,15 +282,15 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do
@handler.process(@mock_request, @mock_response)
end
end
-
+
describe "when searching for model instances" do
- it "should pass HTTP request parameters to model search" do
+ it "should use a common method for determining the request parameters" do
setup_search_request
- @mock_request.stubs(:query).returns(:foo => :baz, :bar => :xyzzy)
+ @handler.stubs(:params).returns(:foo => :baz, :bar => :xyzzy)
@mock_model_class.expects(:search).with do |args|
args[:foo] == :baz and args[:bar] == :xyzzy
- end.returns([])
- @handler.service(@mock_request, @mock_response)
+ end
+ @handler.process(@mock_request, @mock_response)
end
it "should generate a 200 response when a model search call succeeds" do
@@ -247,20 +298,20 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do
@mock_response.expects(:status=).with(200)
@handler.process(@mock_request, @mock_response)
end
-
+
it "should return a list of serialized objects when a model search call succeeds" do
setup_search_request
mock_matches = [1..5].collect {|i| mock("model instance #{i}", :to_yaml => "model instance #{i}") }
@mock_model_class.stubs(:search).returns(mock_matches)
@handler.process(@mock_request, @mock_response)
end
-
- it "should serialize a controller exception when an exception is thrown by destroy" do
- setup_destroy_request
- @mock_model_class.expects(:destroy).raises(ArgumentError)
+
+ it "should serialize a controller exception when an exception is thrown by search" do
+ setup_search_request
+ @mock_model_class.expects(:search).raises(ArgumentError)
@mock_response.expects(:status=).with(404)
- @handler.process(@mock_request, @mock_response)
- end
+ @handler.process(@mock_request, @mock_response)
+ end
end
it "should serialize a controller exception if the request fails" do
diff --git a/spec/unit/network/http/webrick/xmlrpc.rb b/spec/unit/network/http/webrick/xmlrpc.rb
index e69de29bb..e69de29bb 100644..100755
--- a/spec/unit/network/http/webrick/xmlrpc.rb
+++ b/spec/unit/network/http/webrick/xmlrpc.rb
diff --git a/spec/unit/network/server.rb b/spec/unit/network/server.rb
index 5332964c6..5332964c6 100644..100755
--- a/spec/unit/network/server.rb
+++ b/spec/unit/network/server.rb
diff --git a/spec/unit/node.rb b/spec/unit/node.rb
index 08afc5183..4a41dadf9 100755
--- a/spec/unit/node.rb
+++ b/spec/unit/node.rb
@@ -2,7 +2,7 @@
require File.dirname(__FILE__) + '/../spec_helper'
-describe Puppet::Node, " when initializing" do
+describe Puppet::Node, "when initializing" do
before do
@node = Puppet::Node.new("testnode")
end
@@ -61,7 +61,7 @@ describe Puppet::Node, " when initializing" do
end
end
-describe Puppet::Node, " when returning the environment" do
+describe Puppet::Node, "when returning the environment" do
before do
Puppet.settings.stubs(:value).with(:environments).returns("one,two")
Puppet.settings.stubs(:value).with(:environment).returns("one")
@@ -90,7 +90,7 @@ describe Puppet::Node, " when returning the environment" do
end
end
-describe Puppet::Node, " when merging facts" do
+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"))
@@ -131,7 +131,7 @@ describe Puppet::Node, " when merging facts" do
end
end
-describe Puppet::Node, " when indirecting" do
+describe Puppet::Node, "when indirecting" do
it "should redirect to the indirection" do
@indirection = stub 'indirection', :name => :node
Puppet::Node.stubs(:indirection).returns(@indirection)
@@ -159,68 +159,92 @@ describe Puppet::Node do
it "should provide a method for noting that the node has connected"
end
-describe Puppet::Node, " when searching for nodes" do
+describe Puppet::Node, "when generating the list of names to search through" do
before do
- @searcher = Puppet::Node
@facts = Puppet::Node::Facts.new("foo", "hostname" => "yay", "domain" => "domain.com")
@node = Puppet::Node.new("foo")
- Puppet::Node::Facts.stubs(:find).with("foo").returns(@facts)
+
+ Puppet::Node.stubs(:node_facts).returns @facts.values
end
- it "should return the first node found using the generated list of names" do
- @searcher.expects(:find).with("foo").returns(nil)
- @searcher.expects(:find).with("yay.domain.com").returns(@node)
- @searcher.find_by_any_name("foo").should equal(@node)
+ it "should return an array of names" do
+ Puppet::Node.node_names("foo").should be_instance_of(Array)
end
- it "should search for the node by its key first" do
- names = []
- @searcher.expects(:find).with do |name|
- names << name
- names == %w{foo}
- end.returns(@node)
- @searcher.find_by_any_name("foo").should equal(@node)
+ it "should have the node's fqdn as the second name" do
+ Puppet::Node.node_names("foo.domain.com")[1].should == "yay.domain.com"
end
- it "should search for the rest of the names inversely by length" do
- names = []
- @facts.values["fqdn"] = "longer.than.the.normal.fqdn.com"
- @searcher.stubs(:find).with do |name|
- names << name
+ it "should set the fqdn to the node's 'fqdn' fact if it is available" do
+ @facts.values["fqdn"] = "boo.domain.com"
+ Puppet::Node.node_names("foo")[1].should == "boo.domain.com"
+ end
+
+ it "should set the fqdn to the node's hostname and domain if no fqdn is available" do
+ Puppet::Node.node_names("foo")[1].should == "yay.domain.com"
+ end
+
+ it "should contain an entry for each name available by stripping a segment of the fqdn" do
+ @facts.values["fqdn"] = "foo.deep.sub.domain.com"
+ Puppet::Node.node_names("foo")[2].should == "foo.deep.sub.domain"
+ Puppet::Node.node_names("foo")[3].should == "foo.deep.sub"
+ end
+
+ describe "and :node_name is set to 'cert'" do
+ before do
+ Puppet.settings.stubs(:value).with(:node_name).returns "cert"
end
- @searcher.find_by_any_name("foo")
- # Strip off the key
- names.shift
- # And the 'default'
- names.pop
+ it "should use the passed-in key as the first value" do
+ Puppet::Node.node_names("foo")[0].should == "foo"
+ end
+ end
- length = 100
- names.each do |name|
- (name.length < length).should be_true
- length = name.length
+ describe "and :node_name is set to 'facter'" do
+ before do
+ Puppet.settings.stubs(:value).with(:node_name).returns "facter"
end
+
+ it "should use the node's 'hostname' fact as the first value" do
+ Puppet::Node.node_names("foo")[0].should == "yay"
+ end
+ end
+end
+
+describe Puppet::Node, "when searching for nodes" do
+ before do
+ @facts = Puppet::Node::Facts.new("foo", "hostname" => "yay", "domain" => "domain.com")
+ @node = Puppet::Node.new("foo")
+ Puppet::Node::Facts.stubs(:find).with("foo").returns(@facts)
+ end
+
+ it "should use the 'node_names' method to get its list of names to search" do
+ Puppet::Node.expects(:node_names).with{ |*args| args[0] == "foo" }.returns %w{a b}
+ Puppet::Node.stubs(:find)
+ Puppet::Node.find_by_any_name("foo")
+ end
+
+ it "should return the first node found using the generated list of names" do
+ Puppet::Node.expects(:node_names).returns %w{a b}
+ Puppet::Node.expects(:find).with("a").returns(nil)
+ Puppet::Node.expects(:find).with("b").returns(@node)
+ Puppet::Node.find_by_any_name("foo").should equal(@node)
end
it "should attempt to find a default node if no names are found" do
names = []
- @searcher.stubs(:find).with do |name|
+ Puppet::Node.stubs(:find).with do |name|
names << name
end.returns(nil)
- @searcher.find_by_any_name("foo")
+ Puppet::Node.find_by_any_name("foo")
names[-1].should == "default"
end
- it "should flush the node cache using the :filetimeout parameter" do
- node2 = Puppet::Node.new("foo2")
- Puppet[:filetimeout] = -1
- # I couldn't get this to work with :expects
- @searcher.stubs(:find).returns(@node, node2).then.raises(ArgumentError)
- @searcher.find_by_any_name("foo").should equal(@node)
- @searcher.find_by_any_name("foo").should equal(node2)
- end
+ it "should set the node name to the provided key" do
+ Puppet::Node.stubs(:node_names).returns %w{a b}
+ Puppet::Node.stubs(:find).returns @node
- after do
- Puppet.settings.clear
+ @node.expects(:name=).with("foo")
+ Puppet::Node.find_by_any_name("foo")
end
end
diff --git a/spec/unit/parser/collector.rb b/spec/unit/parser/collector.rb
index e1ceb23ed..2dfae6786 100755
--- a/spec/unit/parser/collector.rb
+++ b/spec/unit/parser/collector.rb
@@ -204,6 +204,8 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
@equery = "test = true"
@vquery = proc { |r| true }
+ Puppet.settings.stubs(:value).with(:storeconfigs).returns true
+
@collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, :exported)
end
@@ -217,6 +219,11 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
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 use initialize the Rails support if ActiveRecord is not connected" do
@compiler.stubs(:resources).returns([])
ActiveRecord::Base.expects(:connected?).returns(false)
@@ -375,6 +382,8 @@ describe Puppet::Parser::Collector, "when building its ActiveRecord query for co
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
diff --git a/spec/unit/util/resource_template.rb b/spec/unit/util/resource_template.rb
new file mode 100755
index 000000000..b4d529e5d
--- /dev/null
+++ b/spec/unit/util/resource_template.rb
@@ -0,0 +1,58 @@
+#!/usr/bin/env ruby
+
+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
+ end
+
+ describe "when evaluating" do
+ before do
+ FileTest.stubs(:exist?).returns true
+ File.stubs(:read).returns "eh"
+
+ @template = stub 'template', :result => nil
+ ERB.stubs(:new).returns @template
+
+ @resource = mock 'resource'
+ @wrapper = Puppet::Util::ResourceTemplate.new("/my/template", @resource)
+ end
+
+ 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
+
+ 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.stubs :set_resource_variables
+
+ @wrapper.evaluate
+ end
+
+ 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
+ end
+end
diff --git a/spec/unit/util/warnings.rb b/spec/unit/util/warnings.rb
index 46bd1cc2d..46bd1cc2d 100644..100755
--- a/spec/unit/util/warnings.rb
+++ b/spec/unit/util/warnings.rb
diff --git a/test/lib/rake/puppet_testtask.rb b/test/lib/rake/puppet_testtask.rb
index 6e8e3642a..a4b8d8b7f 100644
--- a/test/lib/rake/puppet_testtask.rb
+++ b/test/lib/rake/puppet_testtask.rb
@@ -1,5 +1,8 @@
#!/usr/bin/env ruby
+require 'rake'
+require 'rake/testtask'
+
module Rake
class PuppetTestTask < Rake::TestTask
def rake_loader
diff --git a/test/network/client/ca.rb b/test/network/client/ca.rb
index 2546642cd..1741c850a 100755
--- a/test/network/client/ca.rb
+++ b/test/network/client/ca.rb
@@ -30,6 +30,7 @@ class TestClientCA < Test::Unit::TestCase
# 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)
diff --git a/test/network/client/master.rb b/test/network/client/master.rb
index c0d14ccee..5399fca13 100755
--- a/test/network/client/master.rb
+++ b/test/network/client/master.rb
@@ -454,17 +454,8 @@ end
Puppet::Node::Facts.indirection.stubs(:save)
- master = client = nil
- assert_nothing_raised() {
- master = Puppet::Network::Handler.master.new(
- :Local => false
- )
- }
- assert_nothing_raised() {
- client = Puppet::Network::Client.master.new(
- :Master => master
- )
- }
+ master = Puppet::Network::Handler.master.new( :Local => false)
+ client = Puppet::Network::Client.master.new( :Master => master)
# Fake that it's local, so it creates the class file
client.local = false
@@ -473,6 +464,7 @@ end
client.expects(:setclasses).with do |array|
array.length == 2 and array.include?("yaytest") and array.include?("bootest")
end
+
assert_nothing_raised {
client.getconfig
}
diff --git a/test/network/handler/master.rb b/test/network/handler/master.rb
index 14587e971..17bf1b3cc 100755
--- a/test/network/handler/master.rb
+++ b/test/network/handler/master.rb
@@ -8,69 +8,51 @@ require 'puppet/network/handler/master'
class TestMaster < Test::Unit::TestCase
include PuppetTest::ServerTest
+ def setup
+ super
+ @master = Puppet::Network::Handler.master.new(:Manifest => tempfile)
+
+ @catalog = stub 'catalog', :extract => ""
+ Puppet::Node::Catalog.stubs(:find).returns(@catalog)
+ end
+
def teardown
super
Puppet::Util::Cacher.invalidate
end
def test_freshness_is_always_now
- master = Puppet::Network::Handler.master.new(
- :Manifest => tempfile,
- :UseNodes => true,
- :Local => true
- )
-
now1 = mock 'now1'
Time.expects(:now).returns(now1)
- assert_equal(master.freshness, now1, "Did not return current time as freshness")
+ assert_equal(@master.freshness, now1, "Did not return current time as freshness")
end
- # Make sure we're correctly doing clientname manipulations.
- # Testing to make sure we always get a hostname and IP address.
- def test_clientname
- # create our master
- master = Puppet::Network::Handler.master.new(
- :Manifest => tempfile,
- :UseNodes => true,
- :Local => true
- )
-
-
- # First check that 'cert' works
- Puppet[:node_name] = "cert"
-
- # Make sure we get the fact data back when nothing is set
- facts = {
- "hostname" => "fact_hostname",
- "domain" => "fact_domain",
- "fqdn" => "fact_hostname.fact_domain",
- "ipaddress" => "fact_ip"
- }
- certhostname = "cert_hostname"
- certdomain = "cert_domain"
- certname = certhostname + "." + certdomain
- certip = "cert_ip"
-
- resname, resip = master.send(:clientname, nil, nil, facts)
- assert_equal(facts["hostname"], resname, "Did not use fact hostname when no certname was present")
- assert_equal(facts["ipaddress"], resip, "Did not use fact ip when no certname was present")
- assert_equal(facts["domain"], "fact_domain", "Did not use fact domain when no certname was present")
- assert_equal(facts["fqdn"], "fact_hostname.fact_domain", "Did not use fact fqdn when no certname was present")
-
- # Now try it with the cert stuff present
- resname, resip = master.send(:clientname, certname, certip, facts)
- assert_equal(certname, resname, "Did not use cert hostname when certname was present")
- assert_equal(certip, resip, "Did not use cert ip when certname was present")
- assert_equal(facts["domain"], certdomain, "Did not use cert domain when certname was present")
- assert_equal(facts["fqdn"], certname, "Did not use cert fqdn when certname was present")
-
- # And reset the node_name stuff and make sure we use it.
- Puppet[:node_name] = :facter
- resname, resip = master.send(:clientname, certname, certip, facts)
- assert_equal(facts["hostname"], resname, "Did not use fact hostname when nodename was set to facter")
- assert_equal(facts["ipaddress"], resip, "Did not use fact ip when nodename was set to facter")
+ 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
-end
+ def test_facts_are_saved
+ facts = mock('facts')
+ Puppet::Node::Facts.expects(:new).returns(facts)
+ facts.expects(:save)
+
+ @master.stubs(:decode_facts)
+ @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)
+
+ @master.stubs(:decode_facts)
+
+ Puppet::Node::Catalog.expects(:find).with("foo.com").returns(@catalog)
+
+ @master.getconfig("facts", "yaml", "foo.com")
+ end
+end