puppet 2.7.5 → 2.7.6

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 (140) hide show
  1. data/CHANGELOG +121 -0
  2. data/conf/redhat/puppet.spec +16 -7
  3. data/lib/puppet.rb +1 -1
  4. data/lib/puppet/application/cert.rb +17 -3
  5. data/lib/puppet/application/device.rb +1 -0
  6. data/lib/puppet/application/kick.rb +0 -2
  7. data/lib/puppet/application/resource.rb +73 -66
  8. data/lib/puppet/configurer/plugin_handler.rb +6 -2
  9. data/lib/puppet/defaults.rb +60 -5
  10. data/lib/puppet/face/ca.rb +11 -2
  11. data/lib/puppet/face/certificate.rb +33 -4
  12. data/lib/puppet/file_serving/fileset.rb +1 -1
  13. data/lib/puppet/file_serving/indirection_hooks.rb +2 -2
  14. data/lib/puppet/file_serving/metadata.rb +43 -4
  15. data/lib/puppet/indirector.rb +0 -1
  16. data/lib/puppet/indirector/request.rb +3 -4
  17. data/lib/puppet/indirector/resource/active_record.rb +3 -10
  18. data/lib/puppet/indirector/resource/ral.rb +2 -2
  19. data/lib/puppet/indirector/rest.rb +1 -1
  20. data/lib/puppet/network/handler/ca.rb +16 -106
  21. data/lib/puppet/network/handler/master.rb +0 -3
  22. data/lib/puppet/network/handler/runner.rb +1 -0
  23. data/lib/puppet/parser/scope.rb +10 -0
  24. data/lib/puppet/provider/file/posix.rb +72 -34
  25. data/lib/puppet/provider/file/windows.rb +100 -0
  26. data/lib/puppet/provider/group/windows_adsi.rb +2 -2
  27. data/lib/puppet/provider/user/windows_adsi.rb +19 -4
  28. data/lib/puppet/resource.rb +16 -0
  29. data/lib/puppet/resource/catalog.rb +1 -1
  30. data/lib/puppet/ssl/certificate.rb +2 -2
  31. data/lib/puppet/ssl/certificate_authority.rb +86 -10
  32. data/lib/puppet/ssl/certificate_authority/interface.rb +64 -19
  33. data/lib/puppet/ssl/certificate_factory.rb +112 -91
  34. data/lib/puppet/ssl/certificate_request.rb +88 -1
  35. data/lib/puppet/ssl/host.rb +20 -3
  36. data/lib/puppet/type/file.rb +15 -34
  37. data/lib/puppet/type/file/group.rb +11 -91
  38. data/lib/puppet/type/file/mode.rb +11 -41
  39. data/lib/puppet/type/file/owner.rb +18 -34
  40. data/lib/puppet/type/file/source.rb +22 -7
  41. data/lib/puppet/type/group.rb +4 -3
  42. data/lib/puppet/type/user.rb +4 -1
  43. data/lib/puppet/util.rb +59 -6
  44. data/lib/puppet/util/adsi.rb +11 -0
  45. data/lib/puppet/util/log.rb +4 -0
  46. data/lib/puppet/util/log/destinations.rb +7 -1
  47. data/lib/puppet/util/monkey_patches.rb +19 -0
  48. data/lib/puppet/util/network_device/config.rb +4 -5
  49. data/lib/puppet/util/settings.rb +5 -0
  50. data/lib/puppet/util/suidmanager.rb +0 -1
  51. data/lib/puppet/util/windows.rb +4 -0
  52. data/lib/puppet/util/windows/error.rb +16 -0
  53. data/lib/puppet/util/windows/security.rb +593 -0
  54. data/spec/integration/defaults_spec.rb +27 -0
  55. data/spec/integration/network/handler_spec.rb +1 -1
  56. data/spec/integration/type/file_spec.rb +382 -145
  57. data/spec/integration/util/windows/security_spec.rb +468 -0
  58. data/spec/shared_behaviours/file_serving.rb +4 -3
  59. data/spec/unit/application/agent_spec.rb +1 -0
  60. data/spec/unit/application/device_spec.rb +5 -0
  61. data/spec/unit/application/resource_spec.rb +62 -101
  62. data/spec/unit/configurer/downloader_spec.rb +2 -2
  63. data/spec/unit/configurer/plugin_handler_spec.rb +15 -8
  64. data/spec/unit/configurer_spec.rb +2 -2
  65. data/spec/unit/face/ca_spec.rb +34 -0
  66. data/spec/unit/face/certificate_spec.rb +168 -1
  67. data/spec/unit/file_serving/fileset_spec.rb +1 -1
  68. data/spec/unit/file_serving/indirection_hooks_spec.rb +1 -1
  69. data/spec/unit/file_serving/metadata_spec.rb +151 -107
  70. data/spec/unit/indirector/certificate_request/ca_spec.rb +0 -3
  71. data/spec/unit/indirector/direct_file_server_spec.rb +10 -9
  72. data/spec/unit/indirector/file_metadata/file_spec.rb +6 -4
  73. data/spec/unit/indirector/request_spec.rb +13 -3
  74. data/spec/unit/indirector/resource/active_record_spec.rb +4 -10
  75. data/spec/unit/indirector/resource/ral_spec.rb +6 -4
  76. data/spec/unit/indirector/rest_spec.rb +5 -6
  77. data/spec/unit/network/handler/ca_spec.rb +86 -0
  78. data/spec/unit/parser/collector_spec.rb +7 -7
  79. data/spec/unit/parser/scope_spec.rb +20 -0
  80. data/spec/unit/provider/file/posix_spec.rb +226 -0
  81. data/spec/unit/provider/file/windows_spec.rb +136 -0
  82. data/spec/unit/provider/group/windows_adsi_spec.rb +7 -2
  83. data/spec/unit/provider/user/windows_adsi_spec.rb +36 -3
  84. data/spec/unit/resource/catalog_spec.rb +20 -10
  85. data/spec/unit/resource_spec.rb +55 -8
  86. data/spec/unit/ssl/certificate_authority/interface_spec.rb +97 -54
  87. data/spec/unit/ssl/certificate_authority_spec.rb +133 -23
  88. data/spec/unit/ssl/certificate_factory_spec.rb +90 -70
  89. data/spec/unit/ssl/certificate_request_spec.rb +62 -1
  90. data/spec/unit/ssl/certificate_spec.rb +20 -14
  91. data/spec/unit/ssl/host_spec.rb +52 -6
  92. data/spec/unit/type/file/content_spec.rb +4 -4
  93. data/spec/unit/type/file/group_spec.rb +34 -96
  94. data/spec/unit/type/file/mode_spec.rb +88 -0
  95. data/spec/unit/type/file/owner_spec.rb +32 -123
  96. data/spec/unit/type/file/source_spec.rb +120 -41
  97. data/spec/unit/type/file_spec.rb +1033 -753
  98. data/spec/unit/type_spec.rb +19 -1
  99. data/spec/unit/util/adsi_spec.rb +19 -0
  100. data/spec/unit/util/log/destinations_spec.rb +75 -0
  101. data/spec/unit/util/log_spec.rb +15 -0
  102. data/spec/unit/util/network_device/config_spec.rb +7 -0
  103. data/spec/unit/util/settings_spec.rb +10 -0
  104. data/spec/unit/util_spec.rb +126 -13
  105. data/test/language/functions.rb +0 -1
  106. data/test/language/snippets.rb +0 -9
  107. data/test/lib/puppettest/exetest.rb +1 -1
  108. data/test/lib/puppettest/servertest.rb +0 -1
  109. data/test/rails/rails.rb +0 -1
  110. data/test/ral/type/filesources.rb +0 -60
  111. metadata +13 -33
  112. data/lib/puppet/network/client.rb +0 -174
  113. data/lib/puppet/network/client/ca.rb +0 -56
  114. data/lib/puppet/network/client/file.rb +0 -6
  115. data/lib/puppet/network/client/proxy.rb +0 -27
  116. data/lib/puppet/network/client/report.rb +0 -26
  117. data/lib/puppet/network/client/runner.rb +0 -10
  118. data/lib/puppet/network/client/status.rb +0 -4
  119. data/lib/puppet/network/http_server.rb +0 -3
  120. data/lib/puppet/network/http_server/mongrel.rb +0 -130
  121. data/lib/puppet/network/http_server/webrick.rb +0 -155
  122. data/lib/puppet/network/xmlrpc/client.rb +0 -211
  123. data/lib/puppet/provider/file/win32.rb +0 -72
  124. data/lib/puppet/sslcertificates.rb +0 -146
  125. data/lib/puppet/sslcertificates/ca.rb +0 -375
  126. data/lib/puppet/sslcertificates/certificate.rb +0 -255
  127. data/lib/puppet/sslcertificates/inventory.rb +0 -38
  128. data/lib/puppet/sslcertificates/support.rb +0 -146
  129. data/spec/integration/network/client_spec.rb +0 -18
  130. data/spec/unit/network/xmlrpc/client_spec.rb +0 -172
  131. data/spec/unit/sslcertificates/ca_spec.rb +0 -106
  132. data/test/certmgr/certmgr.rb +0 -308
  133. data/test/certmgr/inventory.rb +0 -69
  134. data/test/certmgr/support.rb +0 -105
  135. data/test/network/client/ca.rb +0 -69
  136. data/test/network/client/dipper.rb +0 -34
  137. data/test/network/handler/ca.rb +0 -273
  138. data/test/network/server/mongrel_test.rb +0 -99
  139. data/test/network/server/webrick.rb +0 -111
  140. data/test/network/xmlrpc/client.rb +0 -45
@@ -2,8 +2,6 @@
2
2
  require 'spec_helper'
3
3
 
4
4
  require 'puppet/ssl/host'
5
- require 'puppet/sslcertificates'
6
- require 'puppet/sslcertificates/ca'
7
5
  require 'puppet/indirector/certificate_request/ca'
8
6
 
9
7
  describe Puppet::SSL::CertificateRequest::Ca, :unless => Puppet.features.microsoft_windows? do
@@ -14,7 +12,6 @@ describe Puppet::SSL::CertificateRequest::Ca, :unless => Puppet.features.microso
14
12
 
15
13
  Puppet::SSL::Host.ca_location = :local
16
14
  Puppet[:localcacert] = Puppet[:cacert]
17
- Puppet::SSLCertificates::CA.new.mkrootcert
18
15
 
19
16
  @ca = Puppet::SSL::CertificateAuthority.new
20
17
  end
@@ -17,7 +17,8 @@ describe Puppet::Indirector::DirectFileServer do
17
17
 
18
18
  @server = @direct_file_class.new
19
19
 
20
- @uri = "file:///my/local"
20
+ @path = File.expand_path('/my/local')
21
+ @uri = Puppet::Util.path_to_uri(@path).to_s
21
22
 
22
23
  @request = Puppet::Indirector::Request.new(:mytype, :find, @uri)
23
24
  end
@@ -25,12 +26,12 @@ describe Puppet::Indirector::DirectFileServer do
25
26
  describe Puppet::Indirector::DirectFileServer, "when finding a single file" do
26
27
 
27
28
  it "should return nil if the file does not exist" do
28
- FileTest.expects(:exists?).with("/my/local").returns false
29
+ FileTest.expects(:exists?).with(@path).returns false
29
30
  @server.find(@request).should be_nil
30
31
  end
31
32
 
32
33
  it "should return a Content instance created with the full path to the file if the file exists" do
33
- FileTest.expects(:exists?).with("/my/local").returns true
34
+ FileTest.expects(:exists?).with(@path).returns true
34
35
  @model.expects(:new).returns(:mycontent)
35
36
  @server.find(@request).should == :mycontent
36
37
  end
@@ -41,11 +42,11 @@ describe Puppet::Indirector::DirectFileServer do
41
42
  before do
42
43
  @data = mock 'content'
43
44
  @data.stubs(:collect)
44
- FileTest.expects(:exists?).with("/my/local").returns true
45
+ FileTest.expects(:exists?).with(@path).returns true
45
46
  end
46
47
 
47
48
  it "should pass the full path to the instance" do
48
- @model.expects(:new).with { |key, options| key == "/my/local" }.returns(@data)
49
+ @model.expects(:new).with { |key, options| key == @path }.returns(@data)
49
50
  @server.find(@request)
50
51
  end
51
52
 
@@ -60,19 +61,19 @@ describe Puppet::Indirector::DirectFileServer do
60
61
 
61
62
  describe Puppet::Indirector::DirectFileServer, "when searching for multiple files" do
62
63
  it "should return nil if the file does not exist" do
63
- FileTest.expects(:exists?).with("/my/local").returns false
64
+ FileTest.expects(:exists?).with(@path).returns false
64
65
  @server.find(@request).should be_nil
65
66
  end
66
67
 
67
68
  it "should use :path2instances from the terminus_helper to return instances if the file exists" do
68
- FileTest.expects(:exists?).with("/my/local").returns true
69
+ FileTest.expects(:exists?).with(@path).returns true
69
70
  @server.expects(:path2instances)
70
71
  @server.search(@request)
71
72
  end
72
73
 
73
74
  it "should pass the original request to :path2instances" do
74
- FileTest.expects(:exists?).with("/my/local").returns true
75
- @server.expects(:path2instances).with(@request, "/my/local")
75
+ FileTest.expects(:exists?).with(@path).returns true
76
+ @server.expects(:path2instances).with(@request, @path)
76
77
  @server.search(@request)
77
78
  end
78
79
  end
@@ -15,10 +15,11 @@ describe Puppet::Indirector::FileMetadata::File do
15
15
  describe "when creating the instance for a single found file" do
16
16
  before do
17
17
  @metadata = Puppet::Indirector::FileMetadata::File.new
18
- @uri = "file:///my/local"
18
+ @path = File.expand_path('/my/local')
19
+ @uri = Puppet::Util.path_to_uri(@path).to_s
19
20
  @data = mock 'metadata'
20
21
  @data.stubs(:collect)
21
- FileTest.expects(:exists?).with("/my/local").returns true
22
+ FileTest.expects(:exists?).with(@path).returns true
22
23
 
23
24
  @request = Puppet::Indirector::Request.new(:file_metadata, :find, @uri)
24
25
  end
@@ -34,13 +35,14 @@ describe Puppet::Indirector::FileMetadata::File do
34
35
  describe "when searching for multiple files" do
35
36
  before do
36
37
  @metadata = Puppet::Indirector::FileMetadata::File.new
37
- @uri = "file:///my/local"
38
+ @path = File.expand_path('/my/local')
39
+ @uri = Puppet::Util.path_to_uri(@path).to_s
38
40
 
39
41
  @request = Puppet::Indirector::Request.new(:file_metadata, :find, @uri)
40
42
  end
41
43
 
42
44
  it "should collect the attributes of the instances returned" do
43
- FileTest.expects(:exists?).with("/my/local").returns true
45
+ FileTest.expects(:exists?).with(@path).returns true
44
46
  @metadata.expects(:path2instances).returns( [mock("one", :collect => nil), mock("two", :collect => nil)] )
45
47
  @metadata.search(@request)
46
48
  end
@@ -85,13 +85,15 @@ describe Puppet::Indirector::Request do
85
85
  end
86
86
 
87
87
  describe "and the request key is a URI" do
88
+ let(:file) { File.expand_path("/my/file with spaces") }
89
+
88
90
  describe "and the URI is a 'file' URI" do
89
91
  before do
90
- @request = Puppet::Indirector::Request.new(:ind, :method, "file:///my/file with spaces")
92
+ @request = Puppet::Indirector::Request.new(:ind, :method, "#{URI.unescape(Puppet::Util.path_to_uri(file).to_s)}")
91
93
  end
92
94
 
93
95
  it "should set the request key to the unescaped full file path" do
94
- @request.key.should == "/my/file with spaces"
96
+ @request.key.should == file
95
97
  end
96
98
 
97
99
  it "should not set the protocol" do
@@ -133,7 +135,15 @@ describe Puppet::Indirector::Request do
133
135
  end
134
136
 
135
137
  it "should set the :uri attribute to the full URI" do
136
- Puppet::Indirector::Request.new(:ind, :method, "http:///stuff").uri.should == "http:///stuff"
138
+ Puppet::Indirector::Request.new(:ind, :method, "http:///stu ff").uri.should == 'http:///stu ff'
139
+ end
140
+
141
+ it "should not parse relative URI" do
142
+ Puppet::Indirector::Request.new(:ind, :method, "foo/bar").uri.should be_nil
143
+ end
144
+
145
+ it "should not parse opaque URI" do
146
+ Puppet::Indirector::Request.new(:ind, :method, "mailto:joe").uri.should be_nil
137
147
  end
138
148
  end
139
149
 
@@ -48,19 +48,15 @@ describe "Puppet::Resource::ActiveRecord", :if => (Puppet.features.rails? and de
48
48
  subject.search(Puppet::Resource.indirection.request(:search, type, args))
49
49
  end
50
50
 
51
- it "should fail if the type is not known to Puppet" do
52
- expect { search("banana") }.to raise_error Puppet::Error, /Could not find type/
53
- end
54
-
55
51
  it "should return an empty array if no resources match" do
56
- search("exec").should == []
52
+ search("Exec").should == []
57
53
  end
58
54
 
59
55
  # Assert that this is a case-insensitive rule, too.
60
56
  %w{and or AND OR And Or anD oR}.each do |op|
61
57
  it "should fail if asked to search with #{op.inspect}" do
62
58
  filter = [%w{tag == foo}, op, %w{title == bar}]
63
- expect { search("notify", 'localhost', filter) }.
59
+ expect { search("Notify", 'localhost', filter) }.
64
60
  to raise_error Puppet::Error, /not supported/
65
61
  end
66
62
  end
@@ -76,7 +72,7 @@ describe "Puppet::Resource::ActiveRecord", :if => (Puppet.features.rails? and de
76
72
  end
77
73
 
78
74
  it "should return something responding to `to_resource` if a resource matches" do
79
- found = search("exec")
75
+ found = search("Exec")
80
76
  found.length.should == 1
81
77
  found.map do |item|
82
78
  item.should respond_to :to_resource
@@ -95,9 +91,7 @@ describe "Puppet::Resource::ActiveRecord", :if => (Puppet.features.rails? and de
95
91
  Puppet::Rails.init
96
92
  end
97
93
 
98
- let :type do
99
- Puppet::Type.type('notify').name
100
- end
94
+ let :type do 'Notify' end
101
95
 
102
96
  def query(type, host, filter = nil)
103
97
  subject.send :build_active_record_query, type, host, filter
@@ -108,21 +108,23 @@ describe "Puppet::Resource::Ral" do
108
108
  @instance = stub 'instance', :to_ral => @ral_res
109
109
  @request = stub 'request', :key => "user/", :instance => @instance
110
110
  @catalog = stub 'catalog'
111
+ @report = stub 'report'
112
+ @transaction = stub 'transaction', :report => @report
111
113
 
112
114
  Puppet::Resource::Catalog.stubs(:new).returns(@catalog)
113
- @catalog.stubs(:apply)
115
+ @catalog.stubs(:apply).returns(@transaction)
114
116
  @catalog.stubs(:add_resource)
115
117
  end
116
118
 
117
119
  it "should apply a new catalog with a ral object in it" do
118
120
  Puppet::Resource::Catalog.expects(:new).returns(@catalog)
119
121
  @catalog.expects(:add_resource).with(@ral_res)
120
- @catalog.expects(:apply)
121
- Puppet::Resource::Ral.new.save(@request)
122
+ @catalog.expects(:apply).returns(@transaction)
123
+ Puppet::Resource::Ral.new.save(@request).should
122
124
  end
123
125
 
124
126
  it "should return a regular resource that used to be the ral resource" do
125
- Puppet::Resource::Ral.new.save(@request).should == @rebuilt_res
127
+ Puppet::Resource::Ral.new.save(@request).should == [@rebuilt_res, @report]
126
128
  end
127
129
  end
128
130
  end
@@ -91,6 +91,8 @@ describe Puppet::Indirector::REST do
91
91
  end
92
92
 
93
93
  describe "when making http requests" do
94
+ include PuppetSpec::Files
95
+
94
96
  it "should provide a suggestive error message when certificate verify failed" do
95
97
  connection = Net::HTTP.new('my_server', 8140)
96
98
  @searcher.stubs(:network).returns(connection)
@@ -103,11 +105,8 @@ describe Puppet::Indirector::REST do
103
105
  end
104
106
 
105
107
  it "should provide a helpful error message when hostname was not match with server certificate" do
106
- Puppet[:certdnsnames] = 'foo:bar:baz'
107
- csr = OpenSSL::X509::Request.new
108
- csr.subject = OpenSSL::X509::Name.new([['CN', 'not_my_server']])
109
- csr.public_key = OpenSSL::PKey::RSA.generate(Puppet[:keylength]).public_key
110
- cert = Puppet::SSL::CertificateFactory.new('server', csr, csr, 14).result
108
+ Puppet[:confdir] = tmpdir('conf')
109
+ cert = Puppet::SSL::CertificateAuthority.new.generate('not_my_server', :dns_alt_names => 'foo,bar,baz').content
111
110
 
112
111
  connection = Net::HTTP.new('my_server', 8140)
113
112
  @searcher.stubs(:network).returns(connection)
@@ -121,7 +120,7 @@ describe Puppet::Indirector::REST do
121
120
  expect { @searcher.http_request(:get, stub('request')) }.to(
122
121
  raise_error(Puppet::Error, msg) do |error|
123
122
  error.message =~ msg
124
- $1.split(', ').should =~ ['foo', 'bar', 'baz', 'not_my_server']
123
+ $1.split(', ').should =~ %w[DNS:foo DNS:bar DNS:baz DNS:not_my_server not_my_server]
125
124
  end
126
125
  )
127
126
  end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ require 'puppet/network/handler/ca'
4
+
5
+ describe Puppet::Network::Handler::CA do
6
+ include PuppetSpec::Files
7
+
8
+ describe "#getcert" do
9
+ let(:host) { "testhost" }
10
+ let(:x509_name) { OpenSSL::X509::Name.new [['CN', host]] }
11
+ let(:key) { Puppet::SSL::Key.new(host).generate }
12
+
13
+ let(:csr) do
14
+ csr = OpenSSL::X509::Request.new
15
+ csr.subject = x509_name
16
+ csr.public_key = key.public_key
17
+ csr
18
+ end
19
+
20
+ let(:ca) { Puppet::SSL::CertificateAuthority.new }
21
+ let(:cacert) { ca.instance_variable_get(:@certificate) }
22
+
23
+ before :each do
24
+ Puppet[:confdir] = tmpdir('conf')
25
+
26
+ Puppet::SSL::CertificateAuthority.stubs(:ca?).returns true
27
+ Puppet::SSL::CertificateAuthority.stubs(:singleton_instance).returns ca
28
+ end
29
+
30
+ it "should do nothing if the master is not a CA" do
31
+ Puppet::SSL::CertificateAuthority.stubs(:ca?).returns false
32
+
33
+ csr = OpenSSL::X509::Request.new
34
+ subject.getcert(csr.to_pem).should == ''
35
+ end
36
+
37
+ describe "when a certificate already exists for the host" do
38
+ let!(:cert) { ca.generate(host) }
39
+
40
+ it "should return the existing cert if it matches the public key of the CSR" do
41
+ csr.public_key = cert.content.public_key
42
+
43
+ subject.getcert(csr.to_pem).should == [cert.to_s, cacert.to_s]
44
+ end
45
+
46
+ it "should fail if the public key of the CSR does not match the existing cert" do
47
+ expect do
48
+ subject.getcert(csr.to_pem)
49
+ end.to raise_error(Puppet::Error, /Certificate request does not match existing certificate/)
50
+ end
51
+ end
52
+
53
+ describe "when autosign is enabled" do
54
+ before :each do
55
+ Puppet[:autosign] = true
56
+ end
57
+
58
+ it "should return the new cert and the CA cert" do
59
+ cert_str, cacert_str = subject.getcert(csr.to_pem)
60
+
61
+ returned_cert = Puppet::SSL::Certificate.from_s(cert_str)
62
+ returned_cacert = Puppet::SSL::Certificate.from_s(cacert_str)
63
+
64
+ returned_cert.name.should == host
65
+ returned_cacert.content.subject.cmp(cacert.content.subject).should == 0
66
+ end
67
+ end
68
+
69
+ describe "when autosign is disabled" do
70
+ before :each do
71
+ Puppet[:autosign] = false
72
+ end
73
+
74
+ it "should save the CSR without signing it" do
75
+ subject.getcert(csr.to_pem)
76
+
77
+ Puppet::SSL::Certificate.indirection.find(host).should be_nil
78
+ Puppet::SSL::CertificateRequest.indirection.find(host).should be_a(Puppet::SSL::CertificateRequest)
79
+ end
80
+
81
+ it "should not return a cert" do
82
+ subject.getcert(csr.to_pem).should be_nil
83
+ end
84
+ end
85
+ end
86
+ end
@@ -340,7 +340,7 @@ describe Puppet::Parser::Collector, "when collecting exported resources", :if =>
340
340
  host = Puppet::Rails::Host.create!(:name => 'one.local')
341
341
  Puppet::Rails::Resource.
342
342
  create!(:host => host,
343
- :restype => 'notify', :title => 'whammo',
343
+ :restype => 'Notify', :title => 'whammo',
344
344
  :exported => true)
345
345
 
346
346
  result = @collector.evaluate
@@ -354,7 +354,7 @@ describe Puppet::Parser::Collector, "when collecting exported resources", :if =>
354
354
  host = Puppet::Rails::Host.create!(:name => 'one.local')
355
355
  Puppet::Rails::Resource.
356
356
  create!(:host => host,
357
- :restype => 'notify', :title => 'whammo',
357
+ :restype => 'Notify', :title => 'whammo',
358
358
  :exported => true)
359
359
 
360
360
  param = Puppet::Parser::Resource::Param.
@@ -369,7 +369,7 @@ describe Puppet::Parser::Collector, "when collecting exported resources", :if =>
369
369
  host = Puppet::Rails::Host.create!(:name => 'one.local')
370
370
  Puppet::Rails::Resource.
371
371
  create!(:host => host,
372
- :restype => 'notify', :title => 'whammo',
372
+ :restype => 'Notify', :title => 'whammo',
373
373
  :exported => true)
374
374
 
375
375
  @compiler.expects(:add_resource).with do |scope, resource|
@@ -387,7 +387,7 @@ describe Puppet::Parser::Collector, "when collecting exported resources", :if =>
387
387
  host = Puppet::Rails::Host.create!(:name => 'one.local')
388
388
  Puppet::Rails::Resource.
389
389
  create!(:host => host,
390
- :restype => 'notify', :title => 'whammo',
390
+ :restype => 'Notify', :title => 'whammo',
391
391
  :exported => true)
392
392
 
393
393
  got = @collector.evaluate
@@ -401,7 +401,7 @@ describe Puppet::Parser::Collector, "when collecting exported resources", :if =>
401
401
  host = Puppet::Rails::Host.create!(:name => 'one.local')
402
402
  Puppet::Rails::Resource.
403
403
  create!(:host => host,
404
- :restype => 'notify', :title => 'whammo',
404
+ :restype => 'Notify', :title => 'whammo',
405
405
  :exported => true)
406
406
 
407
407
  local = Puppet::Parser::Resource.new('notify', 'whammo', :scope => @scope)
@@ -416,12 +416,12 @@ describe Puppet::Parser::Collector, "when collecting exported resources", :if =>
416
416
  # One that we already collected...
417
417
  db = Puppet::Rails::Resource.
418
418
  create!(:host => host,
419
- :restype => 'notify', :title => 'whammo',
419
+ :restype => 'Notify', :title => 'whammo',
420
420
  :exported => true)
421
421
  # ...and one we didn't.
422
422
  Puppet::Rails::Resource.
423
423
  create!(:host => host,
424
- :restype => 'notify', :title => 'boingy-boingy',
424
+ :restype => 'Notify', :title => 'boingy-boingy',
425
425
  :exported => true)
426
426
 
427
427
  local = Puppet::Parser::Resource.new('notify', 'whammo',
@@ -52,6 +52,26 @@ describe Puppet::Parser::Scope do
52
52
  Puppet::Parser::Scope.ancestors.should include(Puppet::Resource::TypeCollectionHelper)
53
53
  end
54
54
 
55
+ describe "when missing methods are called" do
56
+ before :each do
57
+ @env = Puppet::Node::Environment.new('testing')
58
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new('foo', :environment => @env))
59
+ @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
60
+ end
61
+
62
+ it "should load and call the method if it looks like a function and it exists" do
63
+ @scope.function_sprintf(["%b", 123]).should == "1111011"
64
+ end
65
+
66
+ it "should raise NoMethodError if the method doesn't look like a function" do
67
+ expect { @scope.sprintf(["%b", 123]) }.should raise_error(NoMethodError)
68
+ end
69
+
70
+ it "should raise NoMethodError if the method looks like a function but doesn't exist" do
71
+ expect { @scope.function_fake_bs(['cows']) }.should raise_error(NoMethodError)
72
+ end
73
+ end
74
+
55
75
  describe "when initializing" do
56
76
  it "should extend itself with its environment's Functions module as well as the default" do
57
77
  env = Puppet::Node::Environment.new("myenv")
@@ -0,0 +1,226 @@
1
+ #!/usr/bin/env rspec
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Puppet::Type.type(:file).provider(:posix), :if => Puppet.features.posix? do
6
+ include PuppetSpec::Files
7
+
8
+ let(:path) { tmpfile('posix_file_spec') }
9
+ let(:resource) { Puppet::Type.type(:file).new :path => path, :mode => 0777, :provider => described_class.name }
10
+ let(:provider) { resource.provider }
11
+
12
+ describe "#mode" do
13
+ it "should return a string with the higher-order bits stripped away" do
14
+ FileUtils.touch(path)
15
+ File.chmod(0644, path)
16
+
17
+ provider.mode.should == '644'
18
+ end
19
+
20
+ it "should return absent if the file doesn't exist" do
21
+ provider.mode.should == :absent
22
+ end
23
+ end
24
+
25
+ describe "#mode=" do
26
+ it "should chmod the file to the specified value" do
27
+ FileUtils.touch(path)
28
+ File.chmod(0644, path)
29
+
30
+ provider.mode = '0755'
31
+
32
+ provider.mode.should == '755'
33
+ end
34
+
35
+ it "should pass along any errors encountered" do
36
+ expect do
37
+ provider.mode = '644'
38
+ end.to raise_error(Puppet::Error, /failed to set mode/)
39
+ end
40
+ end
41
+
42
+ describe "#uid2name" do
43
+ it "should return the name of the user identified by the id" do
44
+ Etc.stubs(:getpwuid).with(501).returns(Struct::Passwd.new('jilluser', nil, 501))
45
+
46
+ provider.uid2name(501).should == 'jilluser'
47
+ end
48
+
49
+ it "should return the argument if it's already a name" do
50
+ provider.uid2name('jilluser').should == 'jilluser'
51
+ end
52
+
53
+ it "should return nil if the argument is above the maximum uid" do
54
+ provider.uid2name(Puppet[:maximum_uid] + 1).should == nil
55
+ end
56
+
57
+ it "should return nil if the user doesn't exist" do
58
+ Etc.expects(:getpwuid).raises(ArgumentError, "can't find user for 999")
59
+
60
+ provider.uid2name(999).should == nil
61
+ end
62
+ end
63
+
64
+ describe "#name2uid" do
65
+ it "should return the id of the user if it exists" do
66
+ passwd = Struct::Passwd.new('bobbo', nil, 502)
67
+
68
+ Etc.stubs(:getpwnam).with('bobbo').returns(passwd)
69
+ Etc.stubs(:getpwuid).with(502).returns(passwd)
70
+
71
+ provider.name2uid('bobbo').should == 502
72
+ end
73
+
74
+ it "should return the argument if it's already an id" do
75
+ provider.name2uid('503').should == 503
76
+ end
77
+
78
+ it "should return false if the user doesn't exist" do
79
+ Etc.stubs(:getpwnam).with('chuck').raises(ArgumentError, "can't find user for chuck")
80
+
81
+ provider.name2uid('chuck').should == false
82
+ end
83
+ end
84
+
85
+ describe "#owner" do
86
+ it "should return the uid of the file owner" do
87
+ FileUtils.touch(path)
88
+ owner = File.stat(path).uid
89
+
90
+ provider.owner.should == owner
91
+ end
92
+
93
+ it "should return absent if the file can't be statted" do
94
+ provider.owner.should == :absent
95
+ end
96
+
97
+ it "should warn and return :silly if the value is beyond the maximum uid" do
98
+ stat = stub('stat', :uid => Puppet[:maximum_uid] + 1)
99
+ resource.stubs(:stat).returns(stat)
100
+
101
+ provider.owner.should == :silly
102
+ @logs.should be_any {|log| log.level == :warning and log.message =~ /Apparently using negative UID/}
103
+ end
104
+ end
105
+
106
+ describe "#owner=" do
107
+ it "should set the owner but not the group of the file" do
108
+ File.expects(:lchown).with(15, nil, resource[:path])
109
+
110
+ provider.owner = 15
111
+ end
112
+
113
+ it "should chown a link if managing links" do
114
+ resource[:links] = :manage
115
+ File.expects(:lchown).with(20, nil, resource[:path])
116
+
117
+ provider.owner = 20
118
+ end
119
+
120
+ it "should chown a link target if following links" do
121
+ resource[:links] = :follow
122
+ File.expects(:chown).with(20, nil, resource[:path])
123
+
124
+ provider.owner = 20
125
+ end
126
+
127
+ it "should pass along any error encountered setting the owner" do
128
+ File.expects(:lchown).raises(ArgumentError)
129
+
130
+ expect { provider.owner = 25 }.to raise_error(Puppet::Error, /Failed to set owner to '25'/)
131
+ end
132
+ end
133
+
134
+ describe "#gid2name" do
135
+ it "should return the name of the group identified by the id" do
136
+ Etc.stubs(:getgrgid).with(501).returns(Struct::Passwd.new('unicorns', nil, nil, 501))
137
+
138
+ provider.gid2name(501).should == 'unicorns'
139
+ end
140
+
141
+ it "should return the argument if it's already a name" do
142
+ provider.gid2name('leprechauns').should == 'leprechauns'
143
+ end
144
+
145
+ it "should return nil if the argument is above the maximum gid" do
146
+ provider.gid2name(Puppet[:maximum_uid] + 1).should == nil
147
+ end
148
+
149
+ it "should return nil if the group doesn't exist" do
150
+ Etc.expects(:getgrgid).raises(ArgumentError, "can't find group for 999")
151
+
152
+ provider.gid2name(999).should == nil
153
+ end
154
+ end
155
+
156
+ describe "#name2gid" do
157
+ it "should return the id of the group if it exists" do
158
+ passwd = Struct::Passwd.new('penguins', nil, nil, 502)
159
+
160
+ Etc.stubs(:getgrnam).with('penguins').returns(passwd)
161
+ Etc.stubs(:getgrgid).with(502).returns(passwd)
162
+
163
+ provider.name2gid('penguins').should == 502
164
+ end
165
+
166
+ it "should return the argument if it's already an id" do
167
+ provider.name2gid('503').should == 503
168
+ end
169
+
170
+ it "should return false if the group doesn't exist" do
171
+ Etc.stubs(:getgrnam).with('wombats').raises(ArgumentError, "can't find group for wombats")
172
+
173
+ provider.name2gid('wombats').should == false
174
+ end
175
+
176
+ end
177
+
178
+ describe "#group" do
179
+ it "should return the gid of the file group" do
180
+ FileUtils.touch(path)
181
+ group = File.stat(path).gid
182
+
183
+ provider.group.should == group
184
+ end
185
+
186
+ it "should return absent if the file can't be statted" do
187
+ provider.group.should == :absent
188
+ end
189
+
190
+ it "should warn and return :silly if the value is beyond the maximum gid" do
191
+ stat = stub('stat', :gid => Puppet[:maximum_uid] + 1)
192
+ resource.stubs(:stat).returns(stat)
193
+
194
+ provider.group.should == :silly
195
+ @logs.should be_any {|log| log.level == :warning and log.message =~ /Apparently using negative GID/}
196
+ end
197
+ end
198
+
199
+ describe "#group=" do
200
+ it "should set the group but not the owner of the file" do
201
+ File.expects(:lchown).with(nil, 15, resource[:path])
202
+
203
+ provider.group = 15
204
+ end
205
+
206
+ it "should change the group for a link if managing links" do
207
+ resource[:links] = :manage
208
+ File.expects(:lchown).with(nil, 20, resource[:path])
209
+
210
+ provider.group = 20
211
+ end
212
+
213
+ it "should change the group for a link target if following links" do
214
+ resource[:links] = :follow
215
+ File.expects(:chown).with(nil, 20, resource[:path])
216
+
217
+ provider.group = 20
218
+ end
219
+
220
+ it "should pass along any error encountered setting the group" do
221
+ File.expects(:lchown).raises(ArgumentError)
222
+
223
+ expect { provider.group = 25 }.to raise_error(Puppet::Error, /Failed to set group to '25'/)
224
+ end
225
+ end
226
+ end