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.

Files changed (80) hide show
  1. data/CHANGELOG +49 -0
  2. data/install.rb +6 -2
  3. data/lib/puppet.rb +1 -1
  4. data/lib/puppet/application.rb +16 -8
  5. data/lib/puppet/application/agent.rb +2 -0
  6. data/lib/puppet/application/apply.rb +3 -0
  7. data/lib/puppet/application/master.rb +1 -1
  8. data/lib/puppet/configurer.rb +10 -1
  9. data/lib/puppet/defaults.rb +9 -0
  10. data/lib/puppet/file_serving/fileset.rb +1 -0
  11. data/lib/puppet/indirector/exec.rb +1 -2
  12. data/lib/puppet/indirector/report/yaml.rb +11 -0
  13. data/lib/puppet/node/environment.rb +1 -1
  14. data/lib/puppet/parameter.rb +2 -0
  15. data/lib/puppet/parameter/path.rb +42 -0
  16. data/lib/puppet/parser/compiler.rb +1 -1
  17. data/lib/puppet/parser/lexer.rb +3 -2
  18. data/lib/puppet/parser/parser_support.rb +0 -1
  19. data/lib/puppet/provider/exec/posix.rb +112 -0
  20. data/lib/puppet/provider/exec/shell.rb +17 -0
  21. data/lib/puppet/provider/group/groupadd.rb +3 -0
  22. data/lib/puppet/provider/nameservice/#directoryservice.rb# +519 -0
  23. data/lib/puppet/provider/package/gem.rb +2 -2
  24. data/lib/puppet/provider/package/macports.rb +106 -0
  25. data/lib/puppet/provider/service/debian.rb +6 -2
  26. data/lib/puppet/rails/inventory_node.rb +5 -0
  27. data/lib/puppet/reference/#providers.rb# +123 -0
  28. data/lib/puppet/resource/type_collection.rb +6 -1
  29. data/lib/puppet/simple_graph.rb +1 -1
  30. data/lib/puppet/transaction.rb +1 -1
  31. data/lib/puppet/transaction/report.rb +28 -10
  32. data/lib/puppet/type/cron.rb +3 -1
  33. data/lib/puppet/type/exec.rb +30 -167
  34. data/lib/puppet/type/file.rb +12 -1
  35. data/lib/puppet/type/file/source.rb +1 -0
  36. data/lib/puppet/type/group.rb +11 -1
  37. data/lib/puppet/type/service.rb +19 -11
  38. data/lib/puppet/util/command_line.rb +15 -12
  39. data/lib/puppet/util/command_line/puppetrun +0 -1
  40. data/lib/puppet/util/loadedfile.rb +1 -5
  41. data/lib/puppet/util/metric.rb +3 -5
  42. data/lib/puppet/util/plugins.rb +82 -0
  43. data/spec/integration/configurer_spec.rb +38 -5
  44. data/spec/integration/transaction_spec.rb +43 -42
  45. data/spec/lib/puppet_spec/verbose.rb +9 -0
  46. data/spec/shared_behaviours/path_parameters.rb +185 -0
  47. data/spec/spec_helper.rb +6 -0
  48. data/spec/unit/application/agent_spec.rb +7 -0
  49. data/spec/unit/application/apply_spec.rb +6 -0
  50. data/spec/unit/application/master_spec.rb +2 -2
  51. data/spec/unit/configurer_spec.rb +48 -0
  52. data/spec/unit/file_serving/fileset_spec.rb +8 -0
  53. data/spec/unit/indirector/certificate_status/#file_spec.rb# +188 -0
  54. data/spec/unit/indirector/exec_spec.rb +2 -3
  55. data/spec/unit/indirector/facts/inventory_active_record_spec.rb +5 -1
  56. data/spec/unit/indirector/report/yaml_spec.rb +38 -0
  57. data/spec/unit/node/environment_spec.rb +15 -14
  58. data/spec/unit/parameter/path_spec.rb +24 -0
  59. data/spec/unit/parser/compiler_spec.rb +1 -2
  60. data/spec/unit/parser/lexer_spec.rb +12 -0
  61. data/spec/unit/provider/exec/posix_spec.rb +120 -0
  62. data/spec/unit/provider/exec/shell_spec.rb +50 -0
  63. data/spec/unit/provider/group/groupadd_spec.rb +11 -1
  64. data/spec/unit/provider/package/gem_spec.rb +11 -1
  65. data/spec/unit/provider/package/macports_spec.rb +122 -0
  66. data/spec/unit/provider/service/debian_spec.rb +14 -2
  67. data/spec/unit/resource/#type_collection_spec.rb# +463 -0
  68. data/spec/unit/resource/type_collection_spec.rb +21 -17
  69. data/spec/unit/transaction/report_spec.rb +13 -2
  70. data/spec/unit/type/cron_spec.rb +466 -18
  71. data/spec/unit/type/exec_spec.rb +633 -106
  72. data/spec/unit/type/file/source_spec.rb +1 -0
  73. data/spec/unit/type/group_spec.rb +8 -1
  74. data/spec/unit/type_spec.rb +1 -1
  75. data/spec/unit/util/loadedfile_spec.rb +7 -0
  76. data/spec/unit/util/rdoc/parser_spec.rb +2 -1
  77. data/tasks/rake/git_workflow.rake +3 -1
  78. data/test/ral/type/exec.rb +87 -176
  79. metadata +21 -5
  80. data/lib/puppet/provider/package/darwinport.rb +0 -86
@@ -0,0 +1,9 @@
1
+ # Support code for running stuff with warnings disabled.
2
+ module Kernel
3
+ def with_verbose_disabled
4
+ verbose, $VERBOSE = $VERBOSE, nil
5
+ result = yield
6
+ $VERBOSE = verbose
7
+ return result
8
+ end
9
+ end
@@ -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
@@ -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 :master category" do
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