puppet 2.6.7 → 2.6.8
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/CHANGELOG +49 -0
- data/install.rb +6 -2
- data/lib/puppet.rb +1 -1
- data/lib/puppet/application.rb +16 -8
- data/lib/puppet/application/agent.rb +2 -0
- data/lib/puppet/application/apply.rb +3 -0
- data/lib/puppet/application/master.rb +1 -1
- data/lib/puppet/configurer.rb +10 -1
- data/lib/puppet/defaults.rb +9 -0
- data/lib/puppet/file_serving/fileset.rb +1 -0
- data/lib/puppet/indirector/exec.rb +1 -2
- data/lib/puppet/indirector/report/yaml.rb +11 -0
- data/lib/puppet/node/environment.rb +1 -1
- data/lib/puppet/parameter.rb +2 -0
- data/lib/puppet/parameter/path.rb +42 -0
- data/lib/puppet/parser/compiler.rb +1 -1
- data/lib/puppet/parser/lexer.rb +3 -2
- data/lib/puppet/parser/parser_support.rb +0 -1
- data/lib/puppet/provider/exec/posix.rb +112 -0
- data/lib/puppet/provider/exec/shell.rb +17 -0
- data/lib/puppet/provider/group/groupadd.rb +3 -0
- data/lib/puppet/provider/nameservice/#directoryservice.rb# +519 -0
- data/lib/puppet/provider/package/gem.rb +2 -2
- data/lib/puppet/provider/package/macports.rb +106 -0
- data/lib/puppet/provider/service/debian.rb +6 -2
- data/lib/puppet/rails/inventory_node.rb +5 -0
- data/lib/puppet/reference/#providers.rb# +123 -0
- data/lib/puppet/resource/type_collection.rb +6 -1
- data/lib/puppet/simple_graph.rb +1 -1
- data/lib/puppet/transaction.rb +1 -1
- data/lib/puppet/transaction/report.rb +28 -10
- data/lib/puppet/type/cron.rb +3 -1
- data/lib/puppet/type/exec.rb +30 -167
- data/lib/puppet/type/file.rb +12 -1
- data/lib/puppet/type/file/source.rb +1 -0
- data/lib/puppet/type/group.rb +11 -1
- data/lib/puppet/type/service.rb +19 -11
- data/lib/puppet/util/command_line.rb +15 -12
- data/lib/puppet/util/command_line/puppetrun +0 -1
- data/lib/puppet/util/loadedfile.rb +1 -5
- data/lib/puppet/util/metric.rb +3 -5
- data/lib/puppet/util/plugins.rb +82 -0
- data/spec/integration/configurer_spec.rb +38 -5
- data/spec/integration/transaction_spec.rb +43 -42
- data/spec/lib/puppet_spec/verbose.rb +9 -0
- data/spec/shared_behaviours/path_parameters.rb +185 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/unit/application/agent_spec.rb +7 -0
- data/spec/unit/application/apply_spec.rb +6 -0
- data/spec/unit/application/master_spec.rb +2 -2
- data/spec/unit/configurer_spec.rb +48 -0
- data/spec/unit/file_serving/fileset_spec.rb +8 -0
- data/spec/unit/indirector/certificate_status/#file_spec.rb# +188 -0
- data/spec/unit/indirector/exec_spec.rb +2 -3
- data/spec/unit/indirector/facts/inventory_active_record_spec.rb +5 -1
- data/spec/unit/indirector/report/yaml_spec.rb +38 -0
- data/spec/unit/node/environment_spec.rb +15 -14
- data/spec/unit/parameter/path_spec.rb +24 -0
- data/spec/unit/parser/compiler_spec.rb +1 -2
- data/spec/unit/parser/lexer_spec.rb +12 -0
- data/spec/unit/provider/exec/posix_spec.rb +120 -0
- data/spec/unit/provider/exec/shell_spec.rb +50 -0
- data/spec/unit/provider/group/groupadd_spec.rb +11 -1
- data/spec/unit/provider/package/gem_spec.rb +11 -1
- data/spec/unit/provider/package/macports_spec.rb +122 -0
- data/spec/unit/provider/service/debian_spec.rb +14 -2
- data/spec/unit/resource/#type_collection_spec.rb# +463 -0
- data/spec/unit/resource/type_collection_spec.rb +21 -17
- data/spec/unit/transaction/report_spec.rb +13 -2
- data/spec/unit/type/cron_spec.rb +466 -18
- data/spec/unit/type/exec_spec.rb +633 -106
- data/spec/unit/type/file/source_spec.rb +1 -0
- data/spec/unit/type/group_spec.rb +8 -1
- data/spec/unit/type_spec.rb +1 -1
- data/spec/unit/util/loadedfile_spec.rb +7 -0
- data/spec/unit/util/rdoc/parser_spec.rb +2 -1
- data/tasks/rake/git_workflow.rake +3 -1
- data/test/ral/type/exec.rb +87 -176
- metadata +21 -5
- data/lib/puppet/provider/package/darwinport.rb +0 -86
@@ -0,0 +1,185 @@
|
|
1
|
+
# In order to use this correctly you must define a method to get an instance
|
2
|
+
# of the type being tested, so that this code can remain generic:
|
3
|
+
#
|
4
|
+
# it_should_behave_like "all path parameters", :path do
|
5
|
+
# def instance(path)
|
6
|
+
# Puppet::Type.type(:example).new(
|
7
|
+
# :name => 'foo', :require => 'bar', :path_param => path
|
8
|
+
# )
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# That method will be invoked for each test to create the instance that we
|
12
|
+
# subsequently test through the system; you should ensure that the minimum of
|
13
|
+
# possible attributes are set to keep the tests clean.
|
14
|
+
#
|
15
|
+
# You must also pass the symbolic name of the parameter being tested to the
|
16
|
+
# block, and optionally can pass a hash of additional options to the block.
|
17
|
+
#
|
18
|
+
# The known options are:
|
19
|
+
# :array :: boolean, does this support arrays of paths, default true.
|
20
|
+
|
21
|
+
shared_examples_for "all pathname parameters with arrays" do |win32|
|
22
|
+
path_types = {
|
23
|
+
"unix absolute" => "/foo/bar",
|
24
|
+
"unix relative" => "foo/bar",
|
25
|
+
"win32 absolute" => %q{\foo\bar},
|
26
|
+
"win32 relative" => %q{foo\bar},
|
27
|
+
"drive absolute" => %q{c:\foo\bar},
|
28
|
+
"drive relative" => %q{c:foo\bar}
|
29
|
+
}
|
30
|
+
|
31
|
+
describe "when given an array of paths" do
|
32
|
+
(1..path_types.length).each do |n|
|
33
|
+
path_types.keys.combination(n) do |set|
|
34
|
+
data = path_types.collect { |k, v| set.member?(k) ? v : nil } .compact
|
35
|
+
reject = true
|
36
|
+
only_absolute = set.find { |k| k =~ /relative/ } .nil?
|
37
|
+
only_unix = set.reject { |k| k =~ /unix/ } .length == 0
|
38
|
+
|
39
|
+
if only_absolute and (only_unix or win32) then
|
40
|
+
reject = false
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should #{reject ? 'reject' : 'accept'} #{set.join(", ")}" do
|
44
|
+
if reject then
|
45
|
+
expect { instance(data) }.
|
46
|
+
should raise_error Puppet::Error, /fully qualified/
|
47
|
+
else
|
48
|
+
instance = instance(data)
|
49
|
+
instance[@param].should == data
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should #{reject ? 'reject' : 'accept'} #{set.join(", ")} doubled" do
|
54
|
+
if reject then
|
55
|
+
expect { instance(data + data) }.
|
56
|
+
should raise_error Puppet::Error, /fully qualified/
|
57
|
+
else
|
58
|
+
instance = instance(data + data)
|
59
|
+
instance[@param].should == (data + data)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
shared_examples_for "all path parameters" do |param, options|
|
69
|
+
# Extract and process options to the block.
|
70
|
+
options ||= {}
|
71
|
+
array = options[:array].nil? ? true : options.delete(:array)
|
72
|
+
if options.keys.length > 0 then
|
73
|
+
fail "unknown options for 'all path parameters': " +
|
74
|
+
options.keys.sort.join(', ')
|
75
|
+
end
|
76
|
+
|
77
|
+
def instance(path)
|
78
|
+
fail "we didn't implement the 'instance(path)' method in the it_should_behave_like block"
|
79
|
+
end
|
80
|
+
|
81
|
+
########################################################################
|
82
|
+
# The actual testing code...
|
83
|
+
before :all do
|
84
|
+
@param = param
|
85
|
+
end
|
86
|
+
|
87
|
+
before :each do
|
88
|
+
@file_separator = File::SEPARATOR
|
89
|
+
end
|
90
|
+
after :each do
|
91
|
+
with_verbose_disabled do
|
92
|
+
verbose, $VERBOSE = $VERBOSE, nil
|
93
|
+
File::SEPARATOR = @file_separator
|
94
|
+
$VERBOSE = verbose
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "on a Unix-like platform it" do
|
99
|
+
before :each do
|
100
|
+
with_verbose_disabled do
|
101
|
+
File::SEPARATOR = '/'
|
102
|
+
end
|
103
|
+
Puppet.features.stubs(:microsoft_windows?).returns(false)
|
104
|
+
Puppet.features.stubs(:posix?).returns(true)
|
105
|
+
end
|
106
|
+
|
107
|
+
if array then
|
108
|
+
it_should_behave_like "all pathname parameters with arrays", false
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should accept a fully qualified path" do
|
112
|
+
path = File.join('', 'foo')
|
113
|
+
instance = instance(path)
|
114
|
+
instance[@param].should == path
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should give a useful error when the path is not absolute" do
|
118
|
+
path = 'foo'
|
119
|
+
expect { instance(path) }.
|
120
|
+
should raise_error Puppet::Error, /fully qualified/
|
121
|
+
end
|
122
|
+
|
123
|
+
{ "Unix" => '/', "Win32" => '\\' }.each do |style, slash|
|
124
|
+
%w{q Q a A z Z c C}.sort.each do |drive|
|
125
|
+
it "should reject drive letter '#{drive}' with #{style} path separators" do
|
126
|
+
path = "#{drive}:#{slash}Program Files"
|
127
|
+
expect { instance(path) }.
|
128
|
+
should raise_error Puppet::Error, /fully qualified/
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "on a Windows-like platform it" do
|
135
|
+
before :each do
|
136
|
+
with_verbose_disabled do
|
137
|
+
File::SEPARATOR = '\\'
|
138
|
+
end
|
139
|
+
Puppet.features.stubs(:microsoft_windows?).returns(true)
|
140
|
+
Puppet.features.stubs(:posix?).returns(false)
|
141
|
+
end
|
142
|
+
|
143
|
+
if array then
|
144
|
+
it_should_behave_like "all pathname parameters with arrays", true
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should accept a fully qualified path" do
|
148
|
+
path = File.join('', 'foo')
|
149
|
+
instance = instance(path)
|
150
|
+
instance[@param].should == path
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should give a useful error when the path is not absolute" do
|
154
|
+
path = 'foo'
|
155
|
+
expect { instance(path) }.
|
156
|
+
should raise_error Puppet::Error, /fully qualified/
|
157
|
+
end
|
158
|
+
|
159
|
+
it "also accepts Unix style path separators" do
|
160
|
+
path = '/Program Files'
|
161
|
+
instance = instance(path)
|
162
|
+
instance[@param].should == path
|
163
|
+
end
|
164
|
+
|
165
|
+
{ "Unix" => '/', "Win32" => '\\' }.each do |style, slash|
|
166
|
+
%w{q Q a A z Z c C}.sort.each do |drive|
|
167
|
+
it "should accept drive letter '#{drive}' with #{style} path separators " do
|
168
|
+
path = "#{drive}:#{slash}Program Files"
|
169
|
+
instance = instance(path)
|
170
|
+
instance[@param].should == path
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
{ "UNC paths" => %q{\\foo\bar},
|
176
|
+
"unparsed local paths" => %q{\\?\c:\foo},
|
177
|
+
"unparsed UNC paths" => %q{\\?\foo\bar}
|
178
|
+
}.each do |name, path|
|
179
|
+
it "should accept #{name} as absolute" do
|
180
|
+
instance = instance(path)
|
181
|
+
instance[@param].should == path
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -23,10 +23,16 @@ end
|
|
23
23
|
module PuppetTest
|
24
24
|
end
|
25
25
|
|
26
|
+
require 'pathname'
|
27
|
+
require 'lib/puppet_spec/verbose'
|
26
28
|
require 'lib/puppet_spec/files'
|
27
29
|
require 'monkey_patches/alias_should_to_must'
|
28
30
|
require 'monkey_patches/publicize_methods'
|
29
31
|
|
32
|
+
Pathname.glob("#{dir}/shared_behaviours/**/*.rb") do |behaviour|
|
33
|
+
require behaviour.relative_path_from(Pathname.new(dir))
|
34
|
+
end
|
35
|
+
|
30
36
|
RSpec.configure do |config|
|
31
37
|
config.mock_with :mocha
|
32
38
|
|
@@ -179,6 +179,7 @@ describe Puppet::Application::Agent do
|
|
179
179
|
Puppet.settings.stubs(:print_config)
|
180
180
|
Puppet::SSL::Host.stubs(:ca_location=)
|
181
181
|
Puppet::Transaction::Report.stubs(:terminus_class=)
|
182
|
+
Puppet::Transaction::Report.stubs(:cache_class=)
|
182
183
|
Puppet::Resource::Catalog.stubs(:terminus_class=)
|
183
184
|
Puppet::Resource::Catalog.stubs(:cache_class=)
|
184
185
|
Puppet::Node::Facts.stubs(:terminus_class=)
|
@@ -309,6 +310,12 @@ describe Puppet::Application::Agent do
|
|
309
310
|
@puppetd.setup
|
310
311
|
end
|
311
312
|
|
313
|
+
it "should tell the report handler to cache locally as yaml" do
|
314
|
+
Puppet::Transaction::Report.expects(:cache_class=).with(:yaml)
|
315
|
+
|
316
|
+
@puppetd.setup
|
317
|
+
end
|
318
|
+
|
312
319
|
it "should change the catalog_terminus setting to 'rest'" do
|
313
320
|
Puppet.expects(:[]=).with(:catalog_terminus, :rest)
|
314
321
|
@puppetd.setup
|
@@ -56,6 +56,7 @@ describe Puppet::Application::Apply do
|
|
56
56
|
Puppet.stubs(:parse_config)
|
57
57
|
Puppet::FileBucket::Dipper.stubs(:new)
|
58
58
|
STDIN.stubs(:read)
|
59
|
+
Puppet::Transaction::Report.stubs(:cache_class=)
|
59
60
|
|
60
61
|
@apply.options.stubs(:[]).with(any_parameters)
|
61
62
|
end
|
@@ -113,6 +114,11 @@ describe Puppet::Application::Apply do
|
|
113
114
|
lambda { @apply.setup }.should raise_error(SystemExit)
|
114
115
|
end
|
115
116
|
|
117
|
+
it "should tell the report handler to cache locally as yaml" do
|
118
|
+
Puppet::Transaction::Report.expects(:cache_class=).with(:yaml)
|
119
|
+
|
120
|
+
@apply.setup
|
121
|
+
end
|
116
122
|
end
|
117
123
|
|
118
124
|
describe "when executing" do
|
@@ -176,8 +176,8 @@ describe Puppet::Application::Master do
|
|
176
176
|
lambda { @master.setup }.should raise_error(SystemExit)
|
177
177
|
end
|
178
178
|
|
179
|
-
it "should tell Puppet.settings to use :main,:ssl and :
|
180
|
-
Puppet.settings.expects(:use).with(:main,:master,:ssl)
|
179
|
+
it "should tell Puppet.settings to use :main,:ssl,:master and :metrics category" do
|
180
|
+
Puppet.settings.expects(:use).with(:main,:master,:ssl,:metrics)
|
181
181
|
|
182
182
|
@master.setup
|
183
183
|
end
|
@@ -81,6 +81,7 @@ describe Puppet::Configurer, "when executing a catalog run" do
|
|
81
81
|
@catalog = Puppet::Resource::Catalog.new
|
82
82
|
@catalog.stubs(:apply)
|
83
83
|
@agent.stubs(:retrieve_catalog).returns @catalog
|
84
|
+
@agent.stubs(:save_last_run_summary)
|
84
85
|
|
85
86
|
Puppet::Util::Log.stubs(:newdestination)
|
86
87
|
Puppet::Util::Log.stubs(:close)
|
@@ -225,9 +226,12 @@ describe Puppet::Configurer, "when executing a catalog run" do
|
|
225
226
|
end
|
226
227
|
|
227
228
|
describe Puppet::Configurer, "when sending a report" do
|
229
|
+
include PuppetSpec::Files
|
230
|
+
|
228
231
|
before do
|
229
232
|
Puppet.settings.stubs(:use).returns(true)
|
230
233
|
@configurer = Puppet::Configurer.new
|
234
|
+
Puppet[:lastrunfile] = tmpfile('last_run_file')
|
231
235
|
|
232
236
|
@report = Puppet::Transaction::Report.new("apply")
|
233
237
|
@trans = stub 'transaction'
|
@@ -268,6 +272,20 @@ describe Puppet::Configurer, "when sending a report" do
|
|
268
272
|
@configurer.send_report(@report, nil)
|
269
273
|
end
|
270
274
|
|
275
|
+
it "should save the last run summary if reporting is enabled" do
|
276
|
+
Puppet.settings[:report] = true
|
277
|
+
|
278
|
+
@configurer.expects(:save_last_run_summary).with(@report)
|
279
|
+
@configurer.send_report(@report, nil)
|
280
|
+
end
|
281
|
+
|
282
|
+
it "should save the last run summary if reporting is disabled" do
|
283
|
+
Puppet.settings[:report] = false
|
284
|
+
|
285
|
+
@configurer.expects(:save_last_run_summary).with(@report)
|
286
|
+
@configurer.send_report(@report, nil)
|
287
|
+
end
|
288
|
+
|
271
289
|
it "should log but not fail if saving the report fails" do
|
272
290
|
Puppet.settings[:report] = true
|
273
291
|
|
@@ -278,6 +296,36 @@ describe Puppet::Configurer, "when sending a report" do
|
|
278
296
|
end
|
279
297
|
end
|
280
298
|
|
299
|
+
describe Puppet::Configurer, "when saving the summary report file" do
|
300
|
+
before do
|
301
|
+
Puppet.settings.stubs(:use).returns(true)
|
302
|
+
@configurer = Puppet::Configurer.new
|
303
|
+
|
304
|
+
@report = stub 'report'
|
305
|
+
@trans = stub 'transaction'
|
306
|
+
@lastrunfd = stub 'lastrunfd'
|
307
|
+
Puppet::Util::FileLocking.stubs(:writelock).yields(@lastrunfd)
|
308
|
+
end
|
309
|
+
|
310
|
+
it "should write the raw summary to the lastrunfile setting value" do
|
311
|
+
Puppet::Util::FileLocking.expects(:writelock).with(Puppet[:lastrunfile], 0660)
|
312
|
+
@configurer.save_last_run_summary(@report)
|
313
|
+
end
|
314
|
+
|
315
|
+
it "should write the raw summary as yaml" do
|
316
|
+
@report.expects(:raw_summary).returns("summary")
|
317
|
+
@lastrunfd.expects(:print).with(YAML.dump("summary"))
|
318
|
+
@configurer.save_last_run_summary(@report)
|
319
|
+
end
|
320
|
+
|
321
|
+
it "should log but not fail if saving the last run summary fails" do
|
322
|
+
Puppet::Util::FileLocking.expects(:writelock).raises "exception"
|
323
|
+
Puppet.expects(:err)
|
324
|
+
lambda { @configurer.save_last_run_summary(@report) }.should_not raise_error
|
325
|
+
end
|
326
|
+
|
327
|
+
end
|
328
|
+
|
281
329
|
describe Puppet::Configurer, "when retrieving a catalog" do
|
282
330
|
before do
|
283
331
|
Puppet.settings.stubs(:use).returns(true)
|
@@ -13,6 +13,14 @@ describe Puppet::FileServing::Fileset, " when initializing" do
|
|
13
13
|
proc { Puppet::FileServing::Fileset.new("some/file") }.should raise_error(ArgumentError)
|
14
14
|
end
|
15
15
|
|
16
|
+
it "should not fail if the path is fully qualified, with a trailing separator" do
|
17
|
+
path = "/some/path/with/trailing/separator"
|
18
|
+
path_with_separator = "#{path}#{File::SEPARATOR}"
|
19
|
+
File.stubs(:lstat).with(path).returns stub('stat')
|
20
|
+
fileset = Puppet::FileServing::Fileset.new(path_with_separator)
|
21
|
+
fileset.path.should == path
|
22
|
+
end
|
23
|
+
|
16
24
|
it "should fail if its path does not exist" do
|
17
25
|
File.expects(:lstat).with("/some/file").returns nil
|
18
26
|
proc { Puppet::FileServing::Fileset.new("/some/file") }.should raise_error(ArgumentError)
|
@@ -0,0 +1,188 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper.rb')
|
4
|
+
require 'puppet/ssl/host'
|
5
|
+
require 'puppet/indirector/certificate_status'
|
6
|
+
require 'tempfile'
|
7
|
+
|
8
|
+
describe "Puppet::Indirector::CertificateStatus::File" do
|
9
|
+
include PuppetSpec::Files
|
10
|
+
|
11
|
+
before do
|
12
|
+
Puppet::SSL::CertificateAuthority.stubs(:ca?).returns true
|
13
|
+
@terminus = Puppet::SSL::Host.indirection.terminus(:file)
|
14
|
+
|
15
|
+
@tmpdir = tmpdir("certificate_status_ca_testing")
|
16
|
+
Puppet[:confdir] = @tmpdir
|
17
|
+
Puppet[:vardir] = @tmpdir
|
18
|
+
|
19
|
+
# localcacert is where each client stores the CA certificate
|
20
|
+
# cacert is where the master stores the CA certificate
|
21
|
+
# Since we need to play the role of both for testing we need them to be the same and exist
|
22
|
+
Puppet[:cacert] = Puppet[:localcacert]
|
23
|
+
end
|
24
|
+
|
25
|
+
def generate_csr(host)
|
26
|
+
host.generate_key
|
27
|
+
csr = Puppet::SSL::CertificateRequest.new(host.name)
|
28
|
+
csr.generate(host.key.content)
|
29
|
+
Puppet::SSL::CertificateRequest.indirection.save(csr)
|
30
|
+
end
|
31
|
+
|
32
|
+
def sign_csr(host)
|
33
|
+
host.desired_state = "signed"
|
34
|
+
@terminus.save(Puppet::Indirector::Request.new(:certificate_status, :save, host.name, host))
|
35
|
+
end
|
36
|
+
|
37
|
+
def generate_signed_cert(host)
|
38
|
+
generate_csr(host)
|
39
|
+
sign_csr(host)
|
40
|
+
|
41
|
+
@terminus.find(Puppet::Indirector::Request.new(:certificate_status, :find, host.name, host))
|
42
|
+
end
|
43
|
+
|
44
|
+
def generate_revoked_cert(host)
|
45
|
+
generate_signed_cert(host)
|
46
|
+
|
47
|
+
host.desired_state = "revoked"
|
48
|
+
|
49
|
+
@terminus.save(Puppet::Indirector::Request.new(:certificate_status, :save, host.name, host))
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should be a terminus on SSL::Host" do
|
53
|
+
@terminus.should be_instance_of(Puppet::Indirector::CertificateStatus::File)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should create a CA instance if none is present" do
|
57
|
+
@terminus.ca.should be_instance_of(Puppet::SSL::CertificateAuthority)
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "when creating the CA" do
|
61
|
+
it "should fail if it is not a valid CA" do
|
62
|
+
Puppet::SSL::CertificateAuthority.expects(:ca?).returns false
|
63
|
+
lambda { @terminus.ca }.should raise_error(ArgumentError, "This process is not configured as a certificate authority")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should be indirected with the name 'certificate_status'" do
|
68
|
+
Puppet::SSL::Host.indirection.name.should == :certificate_status
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "when finding" do
|
72
|
+
before do
|
73
|
+
@host = Puppet::SSL::Host.new("foo")
|
74
|
+
Puppet.settings.use(:main)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should return the Puppet::SSL::Host when a CSR exists for the host" do
|
78
|
+
generate_csr(@host)
|
79
|
+
request = Puppet::Indirector::Request.new(:certificate_status, :find, "foo", @host)
|
80
|
+
|
81
|
+
retrieved_host = @terminus.find(request)
|
82
|
+
|
83
|
+
retrieved_host.name.should == @host.name
|
84
|
+
retrieved_host.certificate_request.content.to_s.chomp.should == @host.certificate_request.content.to_s.chomp
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should return the Puppet::SSL::Host when a public key exist for the host" do
|
88
|
+
generate_signed_cert(@host)
|
89
|
+
request = Puppet::Indirector::Request.new(:certificate_status, :find, "foo", @host)
|
90
|
+
|
91
|
+
retrieved_host = @terminus.find(request)
|
92
|
+
|
93
|
+
retrieved_host.name.should == @host.name
|
94
|
+
retrieved_host.certificate.content.to_s.chomp.should == @host.certificate.content.to_s.chomp
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should return nil when neither a CSR nor public key exist for the host" do
|
98
|
+
request = Puppet::Indirector::Request.new(:certificate_status, :find, "foo", @host)
|
99
|
+
@terminus.find(request).should == nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "when saving" do
|
104
|
+
before do
|
105
|
+
@host = Puppet::SSL::Host.new("foobar")
|
106
|
+
Puppet.settings.use(:main)
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "when signing a cert" do
|
110
|
+
before do
|
111
|
+
@host.desired_state = "signed"
|
112
|
+
@request = Puppet::Indirector::Request.new(:certificate_status, :save, "foobar", @host)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should fail if no CSR is on disk" do
|
116
|
+
lambda { @terminus.save(@request) }.should raise_error(Puppet::Error, /certificate request/)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should sign the on-disk CSR when it is present" do
|
120
|
+
signed_host = generate_signed_cert(@host)
|
121
|
+
|
122
|
+
signed_host.state.should == "signed"
|
123
|
+
Puppet::SSL::Certificate.indirection.find("foobar").should be_instance_of(Puppet::SSL::Certificate)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "when revoking a cert" do
|
128
|
+
before do
|
129
|
+
@request = Puppet::Indirector::Request.new(:certificate_status, :save, "foobar", @host)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should fail if no certificate is on disk" do
|
133
|
+
@host.desired_state = "revoked"
|
134
|
+
lambda { @terminus.save(@request) }.should raise_error(Puppet::Error, /Cannot revoke/)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should revoke the certificate when it is present" do
|
138
|
+
generate_revoked_cert(@host)
|
139
|
+
|
140
|
+
@host.state.should == 'revoked'
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "when deleting" do
|
146
|
+
before do
|
147
|
+
Puppet.settings.use(:main)
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should not delete anything if no certificate, request, or key is on disk" do
|
151
|
+
host = Puppet::SSL::Host.new("clean_me")
|
152
|
+
request = Puppet::Indirector::Request.new(:certificate_status, :delete, "clean_me", host)
|
153
|
+
@terminus.destroy(request).should == "Nothing was deleted"
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should clean certs, cert requests, keys" do
|
157
|
+
signed_host = Puppet::SSL::Host.new("clean_signed_cert")
|
158
|
+
generate_signed_cert(signed_host)
|
159
|
+
signed_request = Puppet::Indirector::Request.new(:certificate_status, :delete, "clean_signed_cert", signed_host)
|
160
|
+
@terminus.destroy(signed_request).should == "Deleted for host clean_signed_cert: Puppet::SSL::Certificate, Puppet::SSL::Key"
|
161
|
+
|
162
|
+
requested_host = Puppet::SSL::Host.new("clean_csr")
|
163
|
+
generate_csr(requested_host)
|
164
|
+
csr_request = Puppet::Indirector::Request.new(:certificate_status, :delete, "clean_csr", requested_host)
|
165
|
+
@terminus.destroy(csr_request).should == "Deleted for 'host clean_signed_cert': Puppet::SSL::CertificateRequest, Puppet::SSL::Key"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe "when searching" do
|
170
|
+
it "should return a list of all hosts with certificate requests, signed certs, or revoked certs" do
|
171
|
+
Puppet.settings.use(:main)
|
172
|
+
|
173
|
+
signed_host = Puppet::SSL::Host.new("signed_host")
|
174
|
+
generate_signed_cert(signed_host)
|
175
|
+
|
176
|
+
requested_host = Puppet::SSL::Host.new("requested_host")
|
177
|
+
generate_csr(requested_host)
|
178
|
+
|
179
|
+
revoked_host = Puppet::SSL::Host.new("revoked_host")
|
180
|
+
generate_revoked_cert(revoked_host)
|
181
|
+
|
182
|
+
retrieved_hosts = @terminus.search(Puppet::Indirector::Request.new(:certificate_status, :search, "all", signed_host))
|
183
|
+
|
184
|
+
results = retrieved_hosts.map {|h| [h.name, h.state]}.sort{ |h,i| h[0] <=> i[0] }
|
185
|
+
results.should == [["ca","signed"],["requested_host","requested"],["revoked_host","revoked"],["signed_host","signed"]]
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|