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
@@ -89,28 +89,34 @@ describe Puppet::SSL::Certificate do
89
89
  @certificate.should respond_to(:content)
90
90
  end
91
91
 
92
- describe "#alternate_names" do
93
- before do
94
- Puppet[:certdnsnames] = 'foo:bar:baz'
95
- @csr = OpenSSL::X509::Request.new
96
- @csr.subject = OpenSSL::X509::Name.new([['CN', 'quux']])
97
- @csr.public_key = OpenSSL::PKey::RSA.generate(Puppet[:keylength]).public_key
98
- end
99
-
92
+ describe "#subject_alt_names" do
100
93
  it "should list all alternate names when the extension is present" do
101
- cert = Puppet::SSL::CertificateFactory.new('server', @csr, @csr, 14).result
94
+ key = Puppet::SSL::Key.new('quux')
95
+ key.generate
102
96
 
103
- @certificate = @class.from_s(cert.to_pem)
97
+ csr = Puppet::SSL::CertificateRequest.new('quux')
98
+ csr.generate(key, :dns_alt_names => 'foo, bar,baz')
104
99
 
105
- @certificate.alternate_names.should =~ ['foo', 'bar', 'baz', 'quux']
100
+ raw_csr = csr.content
101
+
102
+ cert = Puppet::SSL::CertificateFactory.build('server', csr, raw_csr, 14)
103
+ certificate = @class.from_s(cert.to_pem)
104
+ certificate.subject_alt_names.
105
+ should =~ ['DNS:foo', 'DNS:bar', 'DNS:baz', 'DNS:quux']
106
106
  end
107
107
 
108
108
  it "should return an empty list of names if the extension is absent" do
109
- cert = Puppet::SSL::CertificateFactory.new('client', @csr, @csr, 14).result
109
+ key = Puppet::SSL::Key.new('quux')
110
+ key.generate
111
+
112
+ csr = Puppet::SSL::CertificateRequest.new('quux')
113
+ csr.generate(key)
110
114
 
111
- @certificate = @class.from_s(cert.to_pem)
115
+ raw_csr = csr.content
112
116
 
113
- @certificate.alternate_names.should == []
117
+ cert = Puppet::SSL::CertificateFactory.build('client', csr, raw_csr, 14)
118
+ certificate = @class.from_s(cert.to_pem)
119
+ certificate.subject_alt_names.should be_empty
114
120
  end
115
121
  end
116
122
 
@@ -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
 
8
6
  # REMIND: Fails on windows because there is no user provider yet
9
7
  describe Puppet::SSL::Host, :fails_on_windows => true do
@@ -16,13 +14,14 @@ describe Puppet::SSL::Host, :fails_on_windows => true do
16
14
  dir = tmpdir("ssl_host_testing")
17
15
  Puppet.settings[:confdir] = dir
18
16
  Puppet.settings[:vardir] = dir
17
+ Puppet.settings.use :main, :ssl
19
18
 
20
19
  @host = Puppet::SSL::Host.new("myname")
21
20
  end
22
21
 
23
22
  after do
24
23
  # Cleaned out any cached localhost instance.
25
- Puppet::SSL::Host.instance_variable_set(:@localhost, nil)
24
+ Puppet::SSL::Host.reset
26
25
  Puppet::SSL::Host.ca_location = :none
27
26
  end
28
27
 
@@ -65,6 +64,12 @@ describe Puppet::SSL::Host, :fails_on_windows => true do
65
64
  Puppet::SSL::Host.should respond_to(:localhost)
66
65
  end
67
66
 
67
+ it "should allow to reset localhost" do
68
+ previous_host = Puppet::SSL::Host.localhost
69
+ Puppet::SSL::Host.reset
70
+ Puppet::SSL::Host.localhost.should_not == previous_host
71
+ end
72
+
68
73
  it "should generate the certificate for the localhost instance if no certificate is available" do
69
74
  host = stub 'host', :key => nil
70
75
  Puppet::SSL::Host.expects(:new).returns host
@@ -75,6 +80,48 @@ describe Puppet::SSL::Host, :fails_on_windows => true do
75
80
  Puppet::SSL::Host.localhost.should equal(host)
76
81
  end
77
82
 
83
+ it "should create a localhost cert if no cert is available and it is a CA with autosign and it is using DNS alt names" do
84
+ Puppet[:autosign] = true
85
+ Puppet[:confdir] = tmpdir('conf')
86
+ Puppet[:dns_alt_names] = "foo,bar,baz"
87
+ ca = Puppet::SSL::CertificateAuthority.new
88
+ Puppet::SSL::CertificateAuthority.stubs(:instance).returns ca
89
+
90
+ localhost = Puppet::SSL::Host.localhost
91
+ cert = localhost.certificate
92
+
93
+ cert.should be_a(Puppet::SSL::Certificate)
94
+ cert.subject_alt_names.should =~ %W[DNS:#{Puppet[:certname]} DNS:foo DNS:bar DNS:baz]
95
+ end
96
+
97
+ context "with dns_alt_names" do
98
+ before :each do
99
+ Puppet[:dns_alt_names] = 'one, two'
100
+
101
+ @key = stub('key content')
102
+ key = stub('key', :generate => true, :content => @key)
103
+ Puppet::SSL::Key.stubs(:new).returns key
104
+ Puppet::SSL::Key.indirection.stubs(:save).with(key)
105
+
106
+ @cr = stub('certificate request')
107
+ Puppet::SSL::CertificateRequest.stubs(:new).returns @cr
108
+ Puppet::SSL::CertificateRequest.indirection.stubs(:save).with(@cr)
109
+ end
110
+
111
+ it "should not include subjectAltName if not the local node" do
112
+ @cr.expects(:generate).with(@key, {})
113
+
114
+ Puppet::SSL::Host.new('not-the-' + Puppet[:certname]).generate
115
+ end
116
+
117
+ it "should include subjectAltName if I am a CA" do
118
+ @cr.expects(:generate).
119
+ with(@key, { :dns_alt_names => Puppet[:dns_alt_names] })
120
+
121
+ Puppet::SSL::Host.localhost
122
+ end
123
+ end
124
+
78
125
  it "should always read the key for the localhost instance in from disk" do
79
126
  host = stub 'host', :certificate => "eh"
80
127
  Puppet::SSL::Host.expects(:new).returns host
@@ -381,7 +428,7 @@ describe Puppet::SSL::Host, :fails_on_windows => true do
381
428
 
382
429
  key = stub 'key', :public_key => mock("public_key"), :content => "mycontent"
383
430
  @host.stubs(:key).returns(key)
384
- @request.expects(:generate).with("mycontent")
431
+ @request.expects(:generate).with("mycontent", {})
385
432
  Puppet::SSL::CertificateRequest.indirection.expects(:save).with(@request)
386
433
 
387
434
  @host.generate_certificate_request.should be_true
@@ -573,7 +620,7 @@ describe Puppet::SSL::Host, :fails_on_windows => true do
573
620
  it "should use the CA to sign its certificate request if it does not have a certificate" do
574
621
  @host.expects(:certificate).returns nil
575
622
 
576
- @ca.expects(:sign).with(@host.name)
623
+ @ca.expects(:sign).with(@host.name, true)
577
624
 
578
625
  @host.generate
579
626
  end
@@ -716,7 +763,6 @@ describe Puppet::SSL::Host, :fails_on_windows => true do
716
763
  before do
717
764
  Puppet[:vardir] = tmpdir("ssl_test_vardir")
718
765
  Puppet[:ssldir] = tmpdir("ssl_test_ssldir")
719
- Puppet::SSLCertificates::CA.new.mkrootcert
720
766
  # localcacert is where each client stores the CA certificate
721
767
  # cacert is where the master stores the CA certificate
722
768
  # Since we need to play the role of both for testing we need them to be the same and exist
@@ -13,7 +13,7 @@ describe content do
13
13
 
14
14
  describe "when determining the checksum type" do
15
15
  it "should use the type specified in the source checksum if a source is set" do
16
- @resource[:source] = "/foo"
16
+ @resource[:source] = File.expand_path("/foo")
17
17
  @resource.parameter(:source).expects(:checksum).returns "{md5lite}eh"
18
18
 
19
19
  @content = content.new(:resource => @resource)
@@ -301,14 +301,14 @@ describe content do
301
301
 
302
302
  describe "from local source", :fails_on_windows => true do
303
303
  before(:each) do
304
- @resource = Puppet::Type.type(:file).new :path => @filename, :backup => false
305
304
  @sourcename = tmpfile('source')
305
+ @resource = Puppet::Type.type(:file).new :path => @filename, :backup => false, :source => @sourcename
306
+
306
307
  @source_content = "source file content"*10000
307
308
  @sourcefile = File.open(@sourcename, 'w') {|f| f.write @source_content}
308
309
 
309
310
  @content = @resource.newattr(:content)
310
- @source = @resource.newattr(:source)
311
- @source.stubs(:metadata).returns stub_everything('metadata', :source => @sourcename, :ftype => 'file')
311
+ @source = @resource.parameter :source #newattr(:source)
312
312
  end
313
313
 
314
314
  it "should copy content from the source to the file" do
@@ -1,122 +1,60 @@
1
1
  #!/usr/bin/env rspec
2
- require 'spec_helper'
3
-
4
- property = Puppet::Type.type(:file).attrclass(:group)
5
-
6
- describe property do
7
- before do
8
- @resource = stub 'resource', :line => "foo", :file => "bar"
9
- @resource.stubs(:[]).returns "foo"
10
- @resource.stubs(:[]).with(:path).returns "/my/file"
11
- @group = property.new :resource => @resource
12
- end
13
-
14
- it "should have a method for testing whether a group is valid" do
15
- @group.must respond_to(:validgroup?)
16
- end
17
-
18
- it "should return the found gid if a group is valid" do
19
- @group.expects(:gid).with("foo").returns 500
20
- @group.validgroup?("foo").should == 500
21
- end
22
-
23
- it "should return false if a group is not valid" do
24
- @group.expects(:gid).with("foo").returns nil
25
- @group.validgroup?("foo").should be_false
26
- end
27
-
28
- describe "when retrieving the current value" do
29
- it "should return :absent if the file cannot stat" do
30
- @resource.expects(:stat).returns nil
31
-
32
- @group.retrieve.should == :absent
33
- end
34
2
 
35
- it "should get the gid from the stat instance from the file" do
36
- stat = stub 'stat', :ftype => "foo"
37
- @resource.expects(:stat).returns stat
38
- stat.expects(:gid).returns 500
39
-
40
- @group.retrieve.should == 500
41
- end
3
+ require 'spec_helper'
42
4
 
43
- it "should warn and return :silly if the found value is higher than the maximum uid value" do
44
- Puppet.settings.expects(:value).with(:maximum_uid).returns 500
5
+ describe Puppet::Type.type(:file).attrclass(:group) do
6
+ include PuppetSpec::Files
45
7
 
46
- stat = stub 'stat', :ftype => "foo"
47
- @resource.expects(:stat).returns stat
48
- stat.expects(:gid).returns 1000
8
+ let(:path) { tmpfile('mode_spec') }
9
+ let(:resource) { Puppet::Type.type(:file).new :path => path, :group => 'users' }
10
+ let(:group) { resource.property(:group) }
49
11
 
50
- @group.expects(:warning)
51
- @group.retrieve.should == :silly
52
- end
12
+ before :each do
13
+ # If the provider was already loaded without root, it won't have the
14
+ # feature, so we have to add it here to test.
15
+ Puppet::Type.type(:file).defaultprovider.has_feature :manages_ownership
53
16
  end
54
17
 
55
- describe "when determining if the file is in sync" do
56
- it "should directly compare the group values if the desired group is an integer" do
57
- @group.should = [10]
58
- @group.must be_safe_insync(10)
59
- end
18
+ describe "#insync?" do
19
+ before :each do
20
+ resource[:group] = ['foos', 'bars']
60
21
 
61
- it "should treat numeric strings as integers" do
62
- @group.should = ["10"]
63
- @group.must be_safe_insync(10)
22
+ resource.provider.stubs(:name2gid).with('foos').returns 1001
23
+ resource.provider.stubs(:name2gid).with('bars').returns 1002
64
24
  end
65
25
 
66
- it "should convert the group name to an integer if the desired group is a string" do
67
- @group.expects(:gid).with("foo").returns 10
68
- @group.should = %w{foo}
26
+ it "should fail if an group's id can't be found by name" do
27
+ resource.provider.stubs(:name2gid).returns nil
69
28
 
70
- @group.must be_safe_insync(10)
29
+ expect { group.insync?(5) }.to raise_error(/Could not find group foos/)
71
30
  end
72
31
 
73
- it "should not validate that groups exist when a group is specified as an integer" do
74
- @group.expects(:gid).never
75
- @group.validgroup?(10)
32
+ it "should use the id for comparisons, not the name" do
33
+ group.insync?('foos').should be_false
76
34
  end
77
35
 
78
- it "should fail if it cannot convert a group name to an integer" do
79
- @group.expects(:gid).with("foo").returns nil
80
- @group.should = %w{foo}
81
-
82
- lambda { @group.safe_insync?(10) }.should raise_error(Puppet::Error)
36
+ it "should return true if the current group is one of the desired group" do
37
+ group.insync?(1001).should be_true
83
38
  end
84
39
 
85
- it "should return false if the groups are not equal" do
86
- @group.should = [10]
87
- @group.should_not be_safe_insync(20)
40
+ it "should return false if the current group is not one of the desired group" do
41
+ group.insync?(1003).should be_false
88
42
  end
89
43
  end
90
44
 
91
- describe "when changing the group" do
92
- before do
93
- @group.should = %w{one}
94
- @group.stubs(:gid).returns 500
95
- end
96
-
97
- it "should chown the file if :links is set to :follow" do
98
- @resource.expects(:[]).with(:links).returns :follow
99
- File.expects(:chown)
100
-
101
- @group.sync
102
- end
103
-
104
- it "should lchown the file if :links is set to :manage" do
105
- @resource.expects(:[]).with(:links).returns :manage
106
- File.expects(:lchown)
107
-
108
- @group.sync
109
- end
45
+ %w[is_to_s should_to_s].each do |prop_to_s|
46
+ describe "##{prop_to_s}" do
47
+ it "should use the name of the user if it can find it" do
48
+ resource.provider.stubs(:gid2name).with(1001).returns 'foos'
110
49
 
111
- it "should use the first valid group in its 'should' list" do
112
- @group.should = %w{one two three}
113
- @group.expects(:validgroup?).with("one").returns nil
114
- @group.expects(:validgroup?).with("two").returns 500
115
- @group.expects(:validgroup?).with("three").never
50
+ group.send(prop_to_s, 1001).should == 'foos'
51
+ end
116
52
 
117
- File.expects(:chown).with(nil, 500, "/my/file")
53
+ it "should use the id of the user if it can't" do
54
+ resource.provider.stubs(:gid2name).with(1001).returns nil
118
55
 
119
- @group.sync
56
+ group.send(prop_to_s, 1001).should == 1001
57
+ end
120
58
  end
121
59
  end
122
60
  end
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env rspec
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Puppet::Type.type(:file).attrclass(:mode) do
6
+ include PuppetSpec::Files
7
+
8
+ let(:path) { tmpfile('mode_spec') }
9
+ let(:resource) { Puppet::Type.type(:file).new :path => path, :mode => 0644 }
10
+ let(:mode) { resource.property(:mode) }
11
+
12
+ describe "#validate" do
13
+ it "should accept values specified as integers" do
14
+ expect { mode.value = 0755 }.not_to raise_error
15
+ end
16
+
17
+ it "should accept values specified as octal numbers in strings" do
18
+ expect { mode.value = '0755' }.not_to raise_error
19
+ end
20
+
21
+ it "should not accept strings other than octal numbers" do
22
+ expect do
23
+ mode.value = 'readable please!'
24
+ end.to raise_error(Puppet::Error, /File modes can only be octal numbers/)
25
+ end
26
+ end
27
+
28
+ describe "#munge" do
29
+ it "should dirmask the value when munging" do
30
+ Dir.mkdir(path)
31
+ mode.value = 0644
32
+
33
+ mode.value.must == '755'
34
+ end
35
+ end
36
+
37
+ describe "#dirmask" do
38
+ before :each do
39
+ Dir.mkdir(path)
40
+ end
41
+
42
+ # This is sort of a redundant test, but its spec is important.
43
+ it "should return the value as a string" do
44
+ mode.dirmask('0644').should be_a(String)
45
+ end
46
+
47
+ it "should accept strings as arguments" do
48
+ mode.dirmask('0644').should == '755'
49
+ end
50
+
51
+ it "should accept integers are arguments" do
52
+ mode.dirmask(0644).should == '755'
53
+ end
54
+
55
+ it "should add execute bits corresponding to read bits for directories" do
56
+ mode.dirmask(0644).should == '755'
57
+ end
58
+
59
+ it "should not add an execute bit when there is no read bit" do
60
+ mode.dirmask(0600).should == '700'
61
+ end
62
+
63
+ it "should not add execute bits for files that aren't directories" do
64
+ resource[:path] = tmpfile('other_file')
65
+ mode.dirmask(0644).should == '644'
66
+ end
67
+ end
68
+
69
+ describe "#insync?" do
70
+ it "should return true if the mode is correct" do
71
+ FileUtils.touch(path)
72
+
73
+ mode.must be_insync('644')
74
+ end
75
+
76
+ it "should return false if the mode is incorrect" do
77
+ FileUtils.touch(path)
78
+
79
+ mode.must_not be_insync('755')
80
+ end
81
+
82
+ it "should return true if the file is a link and we are managing links", :unless => Puppet.features.microsoft_windows? do
83
+ File.symlink('anything', path)
84
+
85
+ mode.must be_insync('644')
86
+ end
87
+ end
88
+ end
@@ -1,149 +1,58 @@
1
1
  #!/usr/bin/env rspec
2
- require 'spec_helper'
3
-
4
- property = Puppet::Type.type(:file).attrclass(:owner)
5
-
6
- describe property do
7
- before do
8
- # FIXME: many of these tests exercise the provider rather than `owner`
9
- # and should be moved into provider tests. ~JW
10
- @provider = Puppet::Type.type(:file).provider(:posix).new
11
- @provider.stubs(:uid).with("one").returns(1)
12
2
 
13
- @resource = stub 'resource', :line => "foo", :file => "bar"
14
- @resource.stubs(:[]).returns "foo"
15
- @resource.stubs(:[]).with(:path).returns "/my/file"
16
- @resource.stubs(:provider).returns @provider
17
-
18
- @owner = property.new :resource => @resource
19
- end
3
+ require 'spec_helper'
20
4
 
21
- it "should have a method for testing whether an owner is valid" do
22
- @provider.must respond_to(:validuser?)
23
- end
5
+ describe Puppet::Type.type(:file).attrclass(:owner) do
6
+ include PuppetSpec::Files
24
7
 
25
- it "should return the found uid if an owner is valid" do
26
- @provider.expects(:uid).with("foo").returns 500
27
- @provider.validuser?("foo").should == 500
28
- end
8
+ let(:path) { tmpfile('mode_spec') }
9
+ let(:resource) { Puppet::Type.type(:file).new :path => path, :owner => 'joeuser' }
10
+ let(:owner) { resource.property(:owner) }
29
11
 
30
- it "should return false if an owner is not valid" do
31
- @provider.expects(:uid).with("foo").returns nil
32
- @provider.validuser?("foo").should be_false
12
+ before :each do
13
+ Puppet.features.stubs(:root?).returns(true)
33
14
  end
34
15
 
35
- describe "when retrieving the current value" do
36
- it "should return :absent if the file cannot stat" do
37
- @resource.expects(:stat).returns nil
38
-
39
- @owner.retrieve.should == :absent
40
- end
41
-
42
- it "should get the uid from the stat instance from the file" do
43
- stat = stub 'stat', :ftype => "foo"
44
- @resource.expects(:stat).returns stat
45
- stat.expects(:uid).returns 500
46
-
47
- @owner.retrieve.should == 500
48
- end
49
-
50
- it "should warn and return :silly if the found value is higher than the maximum uid value" do
51
- Puppet.settings.expects(:value).with(:maximum_uid).returns 500
52
-
53
- stat = stub 'stat', :ftype => "foo"
54
- @resource.expects(:stat).returns stat
55
- stat.expects(:uid).returns 1000
16
+ describe "#insync?" do
17
+ before :each do
18
+ resource[:owner] = ['foo', 'bar']
56
19
 
57
- @provider.expects(:warning)
58
- @owner.retrieve.should == :silly
20
+ resource.provider.stubs(:name2uid).with('foo').returns 1001
21
+ resource.provider.stubs(:name2uid).with('bar').returns 1002
59
22
  end
60
- end
61
-
62
- describe "when determining if the file is in sync" do
63
- describe "and not running as root" do
64
- it "should warn once and return true" do
65
- Puppet.features.expects(:root?).returns false
66
-
67
- @provider.expects(:warnonce)
68
23
 
69
- @owner.should = [10]
70
- @owner.must be_safe_insync(20)
71
- end
72
- end
24
+ it "should fail if an owner's id can't be found by name" do
25
+ resource.provider.stubs(:name2uid).returns nil
73
26
 
74
- before do
75
- Puppet.features.stubs(:root?).returns true
27
+ expect { owner.insync?(5) }.to raise_error(/Could not find user foo/)
76
28
  end
77
29
 
78
- it "should be in sync if 'should' is not provided" do
79
- @owner.must be_safe_insync(10)
30
+ it "should use the id for comparisons, not the name" do
31
+ owner.insync?('foo').should be_false
80
32
  end
81
33
 
82
- it "should directly compare the owner values if the desired owner is an integer" do
83
- @owner.should = [10]
84
- @owner.must be_safe_insync(10)
34
+ it "should return true if the current owner is one of the desired owners" do
35
+ owner.insync?(1001).should be_true
85
36
  end
86
37
 
87
- it "should treat numeric strings as integers" do
88
- @owner.should = ["10"]
89
- @owner.must be_safe_insync(10)
90
- end
91
-
92
- it "should convert the owner name to an integer if the desired owner is a string" do
93
- @provider.expects(:uid).with("foo").returns 10
94
- @owner.should = %w{foo}
95
-
96
- @owner.must be_safe_insync(10)
97
- end
98
-
99
- it "should not validate that users exist when a user is specified as an integer" do
100
- @provider.expects(:uid).never
101
- @provider.validuser?(10)
102
- end
103
-
104
- it "should fail if it cannot convert an owner name to an integer" do
105
- @provider.expects(:uid).with("foo").returns nil
106
- @owner.should = %w{foo}
107
-
108
- lambda { @owner.safe_insync?(10) }.should raise_error(Puppet::Error)
109
- end
110
-
111
- it "should return false if the owners are not equal" do
112
- @owner.should = [10]
113
- @owner.should_not be_safe_insync(20)
38
+ it "should return false if the current owner is not one of the desired owners" do
39
+ owner.insync?(1003).should be_false
114
40
  end
115
41
  end
116
42
 
117
- describe "when changing the owner" do
118
- before do
119
- @owner.should = %w{one}
120
- @owner.stubs(:path).returns "path"
121
- @owner.stubs(:uid).returns 500
122
- end
123
-
124
- it "should chown the file if :links is set to :follow" do
125
- @resource.expects(:[]).with(:links).returns :follow
126
- File.expects(:chown)
127
-
128
- @owner.sync
129
- end
130
-
131
- it "should lchown the file if :links is set to :manage" do
132
- @resource.expects(:[]).with(:links).returns :manage
133
- File.expects(:lchown)
43
+ %w[is_to_s should_to_s].each do |prop_to_s|
44
+ describe "##{prop_to_s}" do
45
+ it "should use the name of the user if it can find it" do
46
+ resource.provider.stubs(:uid2name).with(1001).returns 'foo'
134
47
 
135
- @owner.sync
136
- end
137
-
138
- it "should use the first valid owner in its 'should' list" do
139
- @owner.should = %w{one two three}
140
- @provider.expects(:validuser?).with("one").returns nil
141
- @provider.expects(:validuser?).with("two").returns 500
142
- @provider.expects(:validuser?).with("three").never
48
+ owner.send(prop_to_s, 1001).should == 'foo'
49
+ end
143
50
 
144
- File.expects(:chown).with(500, nil, "/my/file")
51
+ it "should use the id of the user if it can't" do
52
+ resource.provider.stubs(:uid2name).with(1001).returns nil
145
53
 
146
- @owner.sync
54
+ owner.send(prop_to_s, 1001).should == 1001
55
+ end
147
56
  end
148
57
  end
149
58
  end