puppet 2.7.13 → 2.7.14

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 (215) hide show
  1. data/CHANGELOG +144 -1
  2. data/conf/osx/preflight +1 -1
  3. data/conf/redhat/puppet.spec +9 -5
  4. data/conf/suse/puppet.spec +4 -1
  5. data/conf/windows/eventlog/Rakefile +32 -0
  6. data/conf/windows/eventlog/puppetres.dll +0 -0
  7. data/conf/windows/eventlog/puppetres.mc +18 -0
  8. data/ext/rack/files/apache2.conf +3 -0
  9. data/install.rb +23 -1
  10. data/lib/puppet.rb +1 -1
  11. data/lib/puppet/agent.rb +1 -14
  12. data/lib/puppet/application/kick.rb +1 -1
  13. data/lib/puppet/application/module.rb +11 -0
  14. data/lib/puppet/daemon.rb +74 -3
  15. data/lib/puppet/defaults.rb +1 -1
  16. data/lib/puppet/face/certificate.rb +1 -1
  17. data/lib/puppet/face/help/man.erb +1 -1
  18. data/lib/puppet/face/module.rb +17 -0
  19. data/lib/puppet/face/module/build.rb +10 -4
  20. data/lib/puppet/face/module/changes.rb +5 -5
  21. data/lib/puppet/face/module/generate.rb +6 -4
  22. data/lib/puppet/face/module/install.rb +122 -32
  23. data/lib/puppet/face/module/list.rb +234 -33
  24. data/lib/puppet/face/module/search.rb +56 -23
  25. data/lib/puppet/face/module/uninstall.rb +33 -38
  26. data/lib/puppet/face/module/upgrade.rb +84 -0
  27. data/lib/puppet/feature/eventlog.rb +6 -0
  28. data/lib/puppet/forge.rb +67 -122
  29. data/lib/puppet/forge/cache.rb +1 -1
  30. data/lib/puppet/forge/repository.rb +6 -25
  31. data/lib/puppet/indirector/facts/network_device.rb +1 -1
  32. data/lib/puppet/interface/action.rb +1 -1
  33. data/lib/puppet/module.rb +79 -28
  34. data/lib/puppet/module_tool.rb +72 -34
  35. data/lib/puppet/module_tool/applications.rb +12 -14
  36. data/lib/puppet/module_tool/applications/application.rb +21 -19
  37. data/lib/puppet/module_tool/applications/builder.rb +4 -4
  38. data/lib/puppet/module_tool/applications/checksummer.rb +12 -3
  39. data/lib/puppet/module_tool/applications/generator.rb +1 -1
  40. data/lib/puppet/module_tool/applications/installer.rb +163 -34
  41. data/lib/puppet/module_tool/applications/searcher.rb +2 -3
  42. data/lib/puppet/module_tool/applications/uninstaller.rb +84 -36
  43. data/lib/puppet/module_tool/applications/unpacker.rb +4 -26
  44. data/lib/puppet/module_tool/applications/upgrader.rb +109 -0
  45. data/lib/puppet/module_tool/checksums.rb +2 -2
  46. data/lib/puppet/module_tool/contents_description.rb +1 -1
  47. data/lib/puppet/module_tool/dependency.rb +2 -2
  48. data/lib/puppet/module_tool/errors.rb +9 -0
  49. data/lib/puppet/module_tool/errors/base.rb +15 -0
  50. data/lib/puppet/module_tool/errors/installer.rb +90 -0
  51. data/lib/puppet/module_tool/errors/shared.rb +115 -0
  52. data/lib/puppet/module_tool/errors/uninstaller.rb +45 -0
  53. data/lib/puppet/module_tool/errors/upgrader.rb +72 -0
  54. data/lib/puppet/module_tool/metadata.rb +2 -2
  55. data/lib/puppet/module_tool/modulefile.rb +7 -7
  56. data/lib/puppet/module_tool/shared_behaviors.rb +161 -0
  57. data/lib/puppet/module_tool/skeleton.rb +1 -1
  58. data/lib/puppet/node/environment.rb +4 -2
  59. data/lib/puppet/parser/ast/leaf.rb +1 -1
  60. data/lib/puppet/parser/functions/create_resources.rb +3 -2
  61. data/lib/puppet/parser/scope.rb +44 -9
  62. data/lib/puppet/provider/augeas/augeas.rb +2 -2
  63. data/lib/puppet/provider/exec.rb +8 -3
  64. data/lib/puppet/provider/exec/shell.rb +1 -2
  65. data/lib/puppet/provider/nameservice/directoryservice.rb +10 -4
  66. data/lib/puppet/provider/package/gem.rb +1 -1
  67. data/lib/puppet/provider/package/pkg.rb +10 -21
  68. data/lib/puppet/provider/selmodule/semodule.rb +1 -2
  69. data/lib/puppet/provider/service/upstart.rb +33 -17
  70. data/lib/puppet/provider/ssh_authorized_key/parsed.rb +1 -1
  71. data/lib/puppet/rails/inventory_node.rb +7 -7
  72. data/lib/puppet/reports/http.rb +4 -1
  73. data/lib/puppet/reports/tagmail.rb +8 -1
  74. data/lib/puppet/resource/type.rb +1 -1
  75. data/lib/puppet/test/test_helper.rb +138 -0
  76. data/lib/puppet/type.rb +9 -1
  77. data/lib/puppet/type/file.rb +18 -10
  78. data/lib/puppet/type/package.rb +13 -9
  79. data/lib/puppet/type/resources.rb +1 -1
  80. data/lib/puppet/type/ssh_authorized_key.rb +3 -4
  81. data/lib/puppet/type/sshkey.rb +4 -4
  82. data/lib/puppet/type/user.rb +1 -0
  83. data/lib/puppet/type/vlan.rb +1 -1
  84. data/lib/puppet/util.rb +31 -14
  85. data/lib/puppet/util/autoload.rb +1 -1
  86. data/lib/puppet/util/command_line.rb +2 -6
  87. data/lib/puppet/util/instrumentation/indirection_probe.rb +1 -1
  88. data/lib/puppet/util/instrumentation/instrumentable.rb +1 -1
  89. data/lib/puppet/util/instrumentation/listeners/log.rb +1 -1
  90. data/lib/puppet/util/instrumentation/listeners/performance.rb +1 -1
  91. data/lib/puppet/util/log.rb +3 -1
  92. data/lib/puppet/util/log/destinations.rb +38 -0
  93. data/lib/puppet/util/monkey_patches.rb +45 -0
  94. data/lib/puppet/util/network_device/base.rb +1 -1
  95. data/lib/puppet/util/network_device/cisco.rb +1 -1
  96. data/lib/puppet/util/network_device/cisco/facts.rb +1 -1
  97. data/lib/puppet/util/network_device/cisco/interface.rb +1 -1
  98. data/lib/puppet/util/network_device/config.rb +1 -1
  99. data/lib/puppet/util/network_device/ipcalc.rb +1 -1
  100. data/lib/puppet/util/network_device/transport.rb +1 -1
  101. data/lib/puppet/util/network_device/transport/base.rb +1 -1
  102. data/lib/puppet/util/network_device/transport/ssh.rb +1 -1
  103. data/lib/puppet/util/settings.rb +2 -11
  104. data/lib/puppet/util/settings/file_setting.rb +3 -5
  105. data/lib/puppet/util/terminal.rb +16 -0
  106. data/lib/puppet/util/zaml.rb +3 -1
  107. data/lib/semver.rb +15 -7
  108. data/spec/fixtures/releases/jamtur01-apache/metadata.json +1 -1
  109. data/spec/fixtures/unit/parser/lexer/arithmetic_expression.pp +1 -1
  110. data/spec/fixtures/unit/provider/package/pkg/dummy +1 -0
  111. data/spec/fixtures/unit/provider/package/pkg/incomplete +1 -0
  112. data/spec/fixtures/unit/provider/package/pkg/publisher +2 -0
  113. data/spec/fixtures/unit/provider/package/pkg/simple +4 -0
  114. data/spec/fixtures/unit/reports/tagmail/tagmail_email.conf +2 -0
  115. data/spec/fixtures/yaml/report0.25.x.yaml +1 -1
  116. data/spec/fixtures/yaml/report2.6.x.yaml +1 -1
  117. data/spec/integration/faces/documentation_spec.rb +1 -1
  118. data/spec/integration/network/rest_authconfig_spec.rb +1 -1
  119. data/spec/lib/puppet_spec/compiler.rb +6 -0
  120. data/spec/lib/puppet_spec/database.rb +30 -0
  121. data/spec/lib/puppet_spec/files.rb +4 -2
  122. data/spec/shared_behaviours/path_parameters.rb +2 -29
  123. data/spec/shared_contexts/platform.rb +43 -0
  124. data/spec/spec_helper.rb +36 -65
  125. data/spec/unit/agent_spec.rb +0 -32
  126. data/spec/unit/application/kick_spec.rb +2 -2
  127. data/spec/unit/daemon_spec.rb +1 -17
  128. data/spec/unit/face/module/install_spec.rb +158 -0
  129. data/spec/unit/face/module/list_spec.rb +182 -0
  130. data/spec/unit/face/module/search_spec.rb +163 -0
  131. data/spec/unit/face/module/uninstall_spec.rb +77 -0
  132. data/spec/unit/face/module/upgrade_spec.rb +26 -0
  133. data/spec/unit/forge/repository_spec.rb +0 -30
  134. data/spec/unit/forge_spec.rb +28 -86
  135. data/spec/unit/indirector/catalog/active_record_spec.rb +45 -65
  136. data/spec/unit/indirector/facts/inventory_active_record_spec.rb +5 -18
  137. data/spec/unit/indirector/resource/active_record_spec.rb +2 -11
  138. data/spec/unit/indirector/resource/ral_spec.rb +7 -2
  139. data/spec/unit/module_spec.rb +240 -107
  140. data/spec/unit/module_tool/application_spec.rb +3 -5
  141. data/spec/unit/module_tool/applications/application_spec.rb +19 -0
  142. data/spec/unit/module_tool/applications/installer_spec.rb +205 -0
  143. data/spec/unit/module_tool/applications/uninstaller_spec.rb +206 -0
  144. data/spec/unit/module_tool/applications/upgrader_spec.rb +37 -0
  145. data/spec/unit/module_tool/metadata_spec.rb +2 -2
  146. data/spec/unit/module_tool_spec.rb +109 -1
  147. data/spec/unit/node/environment_spec.rb +16 -1
  148. data/spec/unit/parser/ast/leaf_spec.rb +16 -1
  149. data/spec/unit/parser/collector_spec.rb +2 -12
  150. data/spec/unit/parser/functions/create_resources_spec.rb +135 -86
  151. data/spec/unit/parser/functions/generate_spec.rb +2 -10
  152. data/spec/unit/parser/scope_spec.rb +345 -16
  153. data/spec/unit/provider/augeas/augeas_spec.rb +19 -0
  154. data/spec/unit/provider/exec/shell_spec.rb +17 -14
  155. data/spec/unit/provider/exec/windows_spec.rb +1 -7
  156. data/spec/unit/provider/exec_spec.rb +35 -0
  157. data/spec/unit/provider/nameservice/directoryservice_spec.rb +10 -0
  158. data/spec/unit/provider/package/dpkg_spec.rb +2 -1
  159. data/spec/unit/provider/package/gem_spec.rb +15 -0
  160. data/spec/unit/provider/package/openbsd_spec.rb +5 -4
  161. data/spec/unit/provider/package/pacman_spec.rb +3 -2
  162. data/spec/unit/provider/package/pkg_spec.rb +56 -33
  163. data/spec/unit/provider/selmodule_spec.rb +11 -4
  164. data/spec/unit/provider/service/redhat_spec.rb +1 -3
  165. data/spec/unit/provider/service/smf_spec.rb +1 -3
  166. data/spec/unit/provider/service/upstart_spec.rb +38 -0
  167. data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +28 -0
  168. data/spec/unit/rails/host_spec.rb +6 -12
  169. data/spec/unit/rails/param_value_spec.rb +3 -8
  170. data/spec/unit/rails/resource_spec.rb +2 -8
  171. data/spec/unit/reports/http_spec.rb +47 -31
  172. data/spec/unit/reports/tagmail_spec.rb +77 -0
  173. data/spec/unit/resource/type_spec.rb +2 -2
  174. data/spec/unit/resource_spec.rb +18 -20
  175. data/spec/unit/semver_spec.rb +31 -13
  176. data/spec/unit/type/exec_spec.rb +8 -15
  177. data/spec/unit/type/group_spec.rb +0 -9
  178. data/spec/unit/type/package_spec.rb +10 -0
  179. data/spec/unit/type/resources_spec.rb +4 -5
  180. data/spec/unit/type/ssh_authorized_key_spec.rb +4 -15
  181. data/spec/unit/type/sshkey_spec.rb +9 -11
  182. data/spec/unit/type/user_spec.rb +123 -127
  183. data/spec/unit/type_spec.rb +20 -0
  184. data/spec/unit/util/command_line_spec.rb +2 -2
  185. data/spec/unit/util/instrumentation/data_spec.rb +1 -1
  186. data/spec/unit/util/instrumentation/indirection_probe_spec.rb +1 -1
  187. data/spec/unit/util/instrumentation/instrumentable_spec.rb +1 -1
  188. data/spec/unit/util/instrumentation/listener_spec.rb +1 -1
  189. data/spec/unit/util/instrumentation/listeners/log_spec.rb +1 -1
  190. data/spec/unit/util/instrumentation/listeners/performance_spec.rb +1 -1
  191. data/spec/unit/util/instrumentation_spec.rb +1 -1
  192. data/spec/unit/util/log/destinations_spec.rb +4 -8
  193. data/spec/unit/util/log_spec.rb +47 -0
  194. data/spec/unit/util/reference_spec.rb +1 -1
  195. data/spec/unit/util/settings/file_setting_spec.rb +9 -0
  196. data/spec/unit/util/settings_spec.rb +0 -53
  197. data/spec/unit/util/terminal_spec.rb +42 -0
  198. data/spec/unit/util/zaml_spec.rb +7 -0
  199. data/spec/unit/util_spec.rb +63 -20
  200. data/tasks/rake/manpages.rake +1 -1
  201. data/test/data/snippets/arithmetic_expression.pp +1 -1
  202. data/test/other/puppet.rb +0 -1
  203. data/test/util/log.rb +6 -6
  204. metadata +41 -16
  205. data/lib/puppet/external/event-loop.rb +0 -1
  206. data/lib/puppet/external/event-loop/better-definers.rb +0 -367
  207. data/lib/puppet/external/event-loop/event-loop.rb +0 -355
  208. data/lib/puppet/external/event-loop/signal-system.rb +0 -218
  209. data/lib/puppet/face/module/clean.rb +0 -30
  210. data/lib/puppet/module_tool/applications/cleaner.rb +0 -16
  211. data/lib/puppet/module_tool/skeleton/templates/generator/metadata.json +0 -12
  212. data/lib/puppet/module_tool/utils.rb +0 -5
  213. data/lib/puppet/module_tool/utils/interrogation.rb +0 -25
  214. data/spec/integration/module_tool_spec.rb +0 -475
  215. data/spec/unit/module_tool/uninstaller_spec.rb +0 -124
@@ -22,6 +22,16 @@ describe SemVer do
22
22
  end
23
23
  end
24
24
 
25
+ describe '::pre' do
26
+ it 'should append a dash when no dash appears in the string' do
27
+ SemVer.pre('1.2.3').should == '1.2.3-'
28
+ end
29
+
30
+ it 'should not append a dash when a dash appears in the string' do
31
+ SemVer.pre('1.2.3-a').should == '1.2.3-a'
32
+ end
33
+ end
34
+
25
35
  describe '::find_matching' do
26
36
  before :all do
27
37
  @versions = %w[
@@ -77,19 +87,27 @@ describe SemVer do
77
87
  describe '::[]' do
78
88
  it "should produce expected ranges" do
79
89
  tests = {
80
- '1.2.3' => SemVer.new('v1.2.3-') .. SemVer.new('v1.2.3'),
81
- '>1.2.3' => SemVer.new('v1.2.4-') .. SemVer::MAX,
82
- '<1.2.3' => SemVer::MIN ... SemVer.new('v1.2.3-'),
83
- '>=1.2.3' => SemVer.new('v1.2.3-') .. SemVer::MAX,
84
- '<=1.2.3' => SemVer::MIN .. SemVer.new('v1.2.3'),
85
- '>1.2.3 <1.2.5' => SemVer.new('v1.2.4-') ... SemVer.new('v1.2.5-'),
86
- '>=1.2.3 <=1.2.5' => SemVer.new('v1.2.3-') .. SemVer.new('v1.2.5'),
87
- '1.2.3 - 2.3.4' => SemVer.new('v1.2.3-') .. SemVer.new('v2.3.4'),
88
- '~1.2.3' => SemVer.new('v1.2.3-') ... SemVer.new('v1.3.0-'),
89
- '~1.2' => SemVer.new('v1.2.0-') ... SemVer.new('v2.0.0-'),
90
- '~1' => SemVer.new('v1.0.0-') ... SemVer.new('v2.0.0-'),
91
- '1.2.x' => SemVer.new('v1.2.0') ... SemVer.new('v1.3.0-'),
92
- '1.x' => SemVer.new('v1.0.0') ... SemVer.new('v2.0.0-'),
90
+ '1.2.3-alpha' => SemVer.new('v1.2.3-alpha') .. SemVer.new('v1.2.3-alpha'),
91
+ '1.2.3' => SemVer.new('v1.2.3-') .. SemVer.new('v1.2.3'),
92
+ '>1.2.3-alpha' => SemVer.new('v1.2.3-alpha-') .. SemVer::MAX,
93
+ '>1.2.3' => SemVer.new('v1.2.4-') .. SemVer::MAX,
94
+ '<1.2.3-alpha' => SemVer::MIN ... SemVer.new('v1.2.3-alpha'),
95
+ '<1.2.3' => SemVer::MIN ... SemVer.new('v1.2.3-'),
96
+ '>=1.2.3-alpha' => SemVer.new('v1.2.3-alpha') .. SemVer::MAX,
97
+ '>=1.2.3' => SemVer.new('v1.2.3-') .. SemVer::MAX,
98
+ '<=1.2.3-alpha' => SemVer::MIN .. SemVer.new('v1.2.3-alpha'),
99
+ '<=1.2.3' => SemVer::MIN .. SemVer.new('v1.2.3'),
100
+ '>1.2.3-a <1.2.3-b' => SemVer.new('v1.2.3-a-') ... SemVer.new('v1.2.3-b'),
101
+ '>1.2.3 <1.2.5' => SemVer.new('v1.2.4-') ... SemVer.new('v1.2.5-'),
102
+ '>=1.2.3-a <= 1.2.3-b' => SemVer.new('v1.2.3-a') .. SemVer.new('v1.2.3-b'),
103
+ '>=1.2.3 <=1.2.5' => SemVer.new('v1.2.3-') .. SemVer.new('v1.2.5'),
104
+ '1.2.3-a - 2.3.4-b' => SemVer.new('v1.2.3-a') .. SemVer.new('v2.3.4-b'),
105
+ '1.2.3 - 2.3.4' => SemVer.new('v1.2.3-') .. SemVer.new('v2.3.4'),
106
+ '~1.2.3' => SemVer.new('v1.2.3-') ... SemVer.new('v1.3.0-'),
107
+ '~1.2' => SemVer.new('v1.2.0-') ... SemVer.new('v2.0.0-'),
108
+ '~1' => SemVer.new('v1.0.0-') ... SemVer.new('v2.0.0-'),
109
+ '1.2.x' => SemVer.new('v1.2.0') ... SemVer.new('v1.3.0-'),
110
+ '1.x' => SemVer.new('v1.0.0') ... SemVer.new('v2.0.0-'),
93
111
  }
94
112
 
95
113
  tests.each do |vstring, expected|
@@ -187,12 +187,7 @@ describe Puppet::Type.type(:exec) do
187
187
  end
188
188
 
189
189
  describe "when setting user" do
190
- describe "on POSIX systems" do
191
- before :each do
192
- Puppet.features.stubs(:posix?).returns(true)
193
- Puppet.features.stubs(:microsoft_windows?).returns(false)
194
- end
195
-
190
+ describe "on POSIX systems", :as_platform => :posix do
196
191
  it "should fail if we are not root" do
197
192
  Puppet.features.stubs(:root?).returns(false)
198
193
  expect { Puppet::Type.type(:exec).new(:name => '/bin/true whatever', :user => 'input') }.
@@ -208,10 +203,8 @@ describe Puppet::Type.type(:exec) do
208
203
  end
209
204
  end
210
205
 
211
- describe "on Windows systems" do
206
+ describe "on Windows systems", :as_platform => :windows do
212
207
  before :each do
213
- Puppet.features.stubs(:posix?).returns(false)
214
- Puppet.features.stubs(:microsoft_windows?).returns(true)
215
208
  Puppet.features.stubs(:root?).returns(true)
216
209
  end
217
210
 
@@ -489,13 +482,13 @@ describe Puppet::Type.type(:exec) do
489
482
  end
490
483
  end
491
484
  end
485
+ end
492
486
 
493
- describe "when setting creates" do
494
- it_should_behave_like "all path parameters", :creates, :array => true do
495
- def instance(path)
496
- # Specify shell provider so we don't have to care about command validation
497
- Puppet::Type.type(:exec).new(:name => @executable, :creates => path, :provider => :shell)
498
- end
487
+ describe "when setting creates" do
488
+ it_should_behave_like "all path parameters", :creates, :array => true do
489
+ def instance(path)
490
+ # Specify shell provider so we don't have to care about command validation
491
+ Puppet::Type.type(:exec).new(:name => @executable, :creates => path, :provider => :shell)
499
492
  end
500
493
  end
501
494
  end
@@ -3,18 +3,9 @@ require 'spec_helper'
3
3
 
4
4
  describe Puppet::Type.type(:group) do
5
5
  before do
6
- ENV["PATH"] += File::PATH_SEPARATOR + "/usr/sbin" unless ENV["PATH"].split(File::PATH_SEPARATOR).include?("/usr/sbin")
7
6
  @class = Puppet::Type.type(:group)
8
7
  end
9
8
 
10
- it "should have a default provider" do
11
- @class.defaultprovider.should_not be_nil
12
- end
13
-
14
- it "should have a default provider inheriting from Puppet::Provider" do
15
- @class.defaultprovider.ancestors.should be_include(Puppet::Provider)
16
- end
17
-
18
9
  it "should have a system_groups feature" do
19
10
  @class.provider_feature(:system_groups).should_not be_nil
20
11
  end
@@ -270,6 +270,16 @@ describe Puppet::Type.type(:package) do
270
270
  @provider.expects(:install).never
271
271
  @catalog.apply
272
272
  end
273
+
274
+ describe "when ensure is set to 'latest'" do
275
+ it "should not install if the value is in the array" do
276
+ @provider.expects(:latest).returns("3.0")
277
+ @package[:ensure] = "latest"
278
+ @package.property(:ensure).insync?(installed_versions).should be_true
279
+ @provider.expects(:install).never
280
+ @catalog.apply
281
+ end
282
+ end
273
283
  end
274
284
  end
275
285
  end
@@ -51,14 +51,13 @@ describe resources do
51
51
  @resources.generate.collect { |r| r.ref }.should_not include(@host1.ref)
52
52
  end
53
53
 
54
- it "should not include the skipped users", :'fails_on_ruby_1.9.2' => true do
54
+ it "should not include the skipped system users", :'fails_on_ruby_1.9.2' => true do
55
55
  res = Puppet::Type.type(:resources).new :name => :user, :purge => true
56
56
  res.catalog = Puppet::Resource::Catalog.new
57
57
 
58
- users = [
59
- Puppet::Type.type(:user).new(:name => "root")
60
- ]
61
- Puppet::Type.type(:user).expects(:instances).returns users
58
+ root = Puppet::Type.type(:user).new(:name => "root")
59
+ Puppet::Type.type(:user).expects(:instances).returns [ root ]
60
+
62
61
  list = res.generate
63
62
 
64
63
  names = list.collect { |r| r[:name] }
@@ -71,21 +71,10 @@ describe ssh_authorized_key, :unless => Puppet.features.microsoft_windows? do
71
71
 
72
72
  describe "for type" do
73
73
 
74
-
75
- it "should support ssh-dss" do
76
- proc { @class.new(:name => "whev", :type => "ssh-dss", :user => "nobody") }.should_not raise_error
77
- end
78
-
79
- it "should support ssh-rsa" do
80
- proc { @class.new(:name => "whev", :type => "ssh-rsa", :user => "nobody") }.should_not raise_error
81
- end
82
-
83
- it "should support :dsa" do
84
- proc { @class.new(:name => "whev", :type => :dsa, :user => "nobody") }.should_not raise_error
85
- end
86
-
87
- it "should support :rsa" do
88
- proc { @class.new(:name => "whev", :type => :rsa, :user => "nobody") }.should_not raise_error
74
+ [:'ssh-dss', :'ssh-rsa', :rsa, :dsa, :'ecdsa-sha2-nistp256', :'ecdsa-sha2-nistp384', :'ecdsa-sha2-nistp521'].each do |keytype|
75
+ it "should support #{keytype}" do
76
+ proc { @class.new(:name => "whev", :type => keytype, :user => "nobody") }.should_not raise_error
77
+ end
89
78
  end
90
79
 
91
80
  it "should alias :rsa to :ssh-rsa" do
@@ -28,24 +28,22 @@ describe sshkey do
28
28
 
29
29
  describe "when validating values" do
30
30
 
31
- it "should support ssh-dss as a type value" do
32
- proc { @class.new(:name => "foo", :type => "ssh-dss") }.should_not raise_error
31
+ [:'ssh-dss', :'ssh-rsa', :rsa, :dsa, :'ecdsa-sha2-nistp256', :'ecdsa-sha2-nistp384', :'ecdsa-sha2-nistp521'].each do |keytype|
32
+ it "should support #{keytype} as a type value" do
33
+ proc { @class.new(:name => "foo", :type => keytype) }.should_not raise_error
34
+ end
33
35
  end
34
36
 
35
- it "should support ssh-rsa as a type value" do
36
- proc { @class.new(:name => "whev", :type => "ssh-rsa") }.should_not raise_error
37
+ it "should alias :rsa to :ssh-rsa" do
38
+ key = @class.new(:name => "foo", :type => :rsa)
39
+ key.should(:type).should == :'ssh-rsa'
37
40
  end
38
41
 
39
- it "should alias :dsa to ssh-dss as a value for type" do
40
- key = @class.new(:name => "whev", :type => :dsa)
42
+ it "should alias :dsa to :ssh-dss" do
43
+ key = @class.new(:name => "foo", :type => :dsa)
41
44
  key.should(:type).should == :'ssh-dss'
42
45
  end
43
46
 
44
- it "should alias :rsa to ssh-rsa as a value for type" do
45
- key = @class.new(:name => "whev", :type => :rsa)
46
- key.should(:type).should == :'ssh-rsa'
47
- end
48
-
49
47
  it "should not support values other than ssh-dss, ssh-rsa, dsa, rsa for type" do
50
48
  proc { @class.new(:name => "whev", :type => :'ssh-dsa') }.should raise_error(Puppet::Error)
51
49
  end
@@ -1,60 +1,60 @@
1
1
  #!/usr/bin/env rspec
2
2
  require 'spec_helper'
3
3
 
4
- user = Puppet::Type.type(:user)
5
-
6
- describe user do
7
- before do
8
- ENV["PATH"] += File::PATH_SEPARATOR + "/usr/sbin" unless ENV["PATH"].split(File::PATH_SEPARATOR).include?("/usr/sbin")
9
- @provider = stub 'provider'
10
- @resource = stub 'resource', :resource => nil, :provider => @provider, :line => nil, :file => nil
11
- end
12
-
13
- it "should have a default provider inheriting from Puppet::Provider" do
14
- user.defaultprovider.ancestors.should be_include(Puppet::Provider)
4
+ describe Puppet::Type.type(:user) do
5
+ before :each do
6
+ @provider_class = described_class.provide(:simple) do
7
+ has_features :manages_expiry, :manages_password_age, :manages_passwords, :manages_solaris_rbac
8
+ mk_resource_methods
9
+ def create; end
10
+ def delete; end
11
+ def exists?; get(:ensure) != :absent; end
12
+ def flush; end
13
+ def self.instances; []; end
14
+ end
15
+ described_class.stubs(:defaultprovider).returns @provider_class
15
16
  end
16
17
 
17
18
  it "should be able to create a instance" do
18
- user.new(:name => "foo").should_not be_nil
19
+ described_class.new(:name => "foo").should_not be_nil
19
20
  end
20
21
 
21
22
  it "should have an allows_duplicates feature" do
22
- user.provider_feature(:allows_duplicates).should_not be_nil
23
+ described_class.provider_feature(:allows_duplicates).should_not be_nil
23
24
  end
24
25
 
25
26
  it "should have an manages_homedir feature" do
26
- user.provider_feature(:manages_homedir).should_not be_nil
27
+ described_class.provider_feature(:manages_homedir).should_not be_nil
27
28
  end
28
29
 
29
30
  it "should have an manages_passwords feature" do
30
- user.provider_feature(:manages_passwords).should_not be_nil
31
+ described_class.provider_feature(:manages_passwords).should_not be_nil
31
32
  end
32
33
 
33
34
  it "should have a manages_solaris_rbac feature" do
34
- user.provider_feature(:manages_solaris_rbac).should_not be_nil
35
+ described_class.provider_feature(:manages_solaris_rbac).should_not be_nil
35
36
  end
36
37
 
37
38
  it "should have a manages_expiry feature" do
38
- user.provider_feature(:manages_expiry).should_not be_nil
39
+ described_class.provider_feature(:manages_expiry).should_not be_nil
39
40
  end
40
41
 
41
42
  it "should have a manages_password_age feature" do
42
- user.provider_feature(:manages_password_age).should_not be_nil
43
+ described_class.provider_feature(:manages_password_age).should_not be_nil
43
44
  end
44
45
 
45
46
  it "should have a system_users feature" do
46
- user.provider_feature(:system_users).should_not be_nil
47
+ described_class.provider_feature(:system_users).should_not be_nil
47
48
  end
48
49
 
49
50
  describe "instances" do
50
- it "should have a valid provider" do
51
- user.new(:name => "foo").provider.class.ancestors.should be_include(Puppet::Provider)
52
- end
53
-
54
51
  it "should delegate existence questions to its provider" do
55
- instance = user.new(:name => "foo")
56
- instance.provider.expects(:exists?).returns "eh"
57
- instance.exists?.should == "eh"
52
+ @provider = @provider_class.new(:name => 'foo', :ensure => :absent)
53
+ instance = described_class.new(:name => "foo", :provider => @provider)
54
+ instance.exists?.should == false
55
+
56
+ @provider.set(:ensure => :present)
57
+ instance.exists?.should == true
58
58
  end
59
59
  end
60
60
 
@@ -62,11 +62,11 @@ describe user do
62
62
 
63
63
  properties.each do |property|
64
64
  it "should have a #{property} property" do
65
- user.attrclass(property).ancestors.should be_include(Puppet::Property)
65
+ described_class.attrclass(property).ancestors.should be_include(Puppet::Property)
66
66
  end
67
67
 
68
68
  it "should have documentation for its #{property} property" do
69
- user.attrclass(property).doc.should be_instance_of(String)
69
+ described_class.attrclass(property).doc.should be_instance_of(String)
70
70
  end
71
71
  end
72
72
 
@@ -74,28 +74,26 @@ describe user do
74
74
 
75
75
  list_properties.each do |property|
76
76
  it "should have a list '#{property}'" do
77
- user.attrclass(property).ancestors.should be_include(Puppet::Property::List)
77
+ described_class.attrclass(property).ancestors.should be_include(Puppet::Property::List)
78
78
  end
79
79
  end
80
80
 
81
81
  it "should have an ordered list 'profiles'" do
82
- user.attrclass(:profiles).ancestors.should be_include(Puppet::Property::OrderedList)
82
+ described_class.attrclass(:profiles).ancestors.should be_include(Puppet::Property::OrderedList)
83
83
  end
84
84
 
85
85
  it "should have key values 'keys'" do
86
- user.attrclass(:keys).ancestors.should be_include(Puppet::Property::KeyValue)
86
+ described_class.attrclass(:keys).ancestors.should be_include(Puppet::Property::KeyValue)
87
87
  end
88
88
 
89
89
  describe "when retrieving all current values" do
90
90
  before do
91
- @user = user.new(:name => "foo", :uid => 10)
91
+ @provider = @provider_class.new(:name => 'foo', :ensure => :present, :uid => 15, :gid => 15)
92
+ @user = described_class.new(:name => "foo", :uid => 10, :provider => @provider)
92
93
  end
93
94
 
94
95
  it "should return a hash containing values for all set properties" do
95
96
  @user[:gid] = 10
96
- @user.property(:ensure).expects(:retrieve).returns :present
97
- @user.property(:uid).expects(:retrieve).returns 15
98
- @user.property(:gid).expects(:retrieve).returns 15
99
97
  values = @user.retrieve
100
98
  [@user.property(:uid), @user.property(:gid)].each { |property| values.should be_include(property) }
101
99
  end
@@ -107,178 +105,190 @@ describe user do
107
105
  end
108
106
 
109
107
  it "should include the result of retrieving each property's current value if the user is present" do
110
- @user.property(:ensure).expects(:retrieve).returns :present
111
- @user.property(:uid).expects(:retrieve).returns 15
112
108
  @user.retrieve[@user.property(:uid)].should == 15
113
109
  end
114
110
  end
115
111
 
116
112
  describe "when managing the ensure property" do
117
- before do
118
- @ensure = user.attrclass(:ensure).new(:resource => @resource)
119
- end
120
-
121
113
  it "should support a :present value" do
122
- lambda { @ensure.should = :present }.should_not raise_error
114
+ lambda { described_class.new(:name => 'foo', :ensure => :present) }.should_not raise_error
123
115
  end
124
116
 
125
117
  it "should support an :absent value" do
126
- lambda { @ensure.should = :absent }.should_not raise_error
118
+ lambda { described_class.new(:name => 'foo', :ensure => :absent) }.should_not raise_error
127
119
  end
128
120
 
129
121
  it "should call :create on the provider when asked to sync to the :present state" do
122
+ @provider = @provider_class.new(:name => 'foo', :ensure => :absent)
130
123
  @provider.expects(:create)
131
- @ensure.should = :present
132
- @ensure.sync
124
+ described_class.new(:name => 'foo', :ensure => :present, :provider => @provider).parameter(:ensure).sync
133
125
  end
134
126
 
135
127
  it "should call :delete on the provider when asked to sync to the :absent state" do
128
+ @provider = @provider_class.new(:name => 'foo', :ensure => :present)
136
129
  @provider.expects(:delete)
137
- @ensure.should = :absent
138
- @ensure.sync
130
+ described_class.new(:name => 'foo', :ensure => :absent, :provider => @provider).parameter(:ensure).sync
139
131
  end
140
132
 
141
133
  describe "and determining the current state" do
142
134
  it "should return :present when the provider indicates the user exists" do
143
- @provider.expects(:exists?).returns true
144
- @ensure.retrieve.should == :present
135
+ @provider = @provider_class.new(:name => 'foo', :ensure => :present)
136
+ described_class.new(:name => 'foo', :ensure => :absent, :provider => @provider).parameter(:ensure).retrieve.should == :present
145
137
  end
146
138
 
147
139
  it "should return :absent when the provider indicates the user does not exist" do
148
- @provider.expects(:exists?).returns false
149
- @ensure.retrieve.should == :absent
140
+ @provider = @provider_class.new(:name => 'foo', :ensure => :absent)
141
+ described_class.new(:name => 'foo', :ensure => :present, :provider => @provider).parameter(:ensure).retrieve.should == :absent
150
142
  end
151
143
  end
152
144
  end
153
145
 
154
146
  describe "when managing the uid property" do
155
147
  it "should convert number-looking strings into actual numbers" do
156
- uid = user.attrclass(:uid).new(:resource => @resource)
157
- uid.should = "50"
158
- uid.should.must == 50
148
+ described_class.new(:name => 'foo', :uid => '50')[:uid].should == 50
159
149
  end
160
150
 
161
151
  it "should support UIDs as numbers" do
162
- uid = user.attrclass(:uid).new(:resource => @resource)
163
- uid.should = 50
164
- uid.should.must == 50
152
+ described_class.new(:name => 'foo', :uid => 50)[:uid].should == 50
165
153
  end
166
154
 
167
- it "should :absent as a value" do
168
- uid = user.attrclass(:uid).new(:resource => @resource)
169
- uid.should = :absent
170
- uid.should.must == :absent
155
+ it "should support :absent as a value" do
156
+ described_class.new(:name => 'foo', :uid => :absent)[:uid].should == :absent
171
157
  end
172
158
  end
173
159
 
174
160
  describe "when managing the gid" do
175
- it "should :absent as a value" do
176
- gid = user.attrclass(:gid).new(:resource => @resource)
177
- gid.should = :absent
178
- gid.should.must == :absent
161
+ it "should support :absent as a value" do
162
+ described_class.new(:name => 'foo', :gid => :absent)[:gid].should == :absent
179
163
  end
180
164
 
181
165
  it "should convert number-looking strings into actual numbers" do
182
- gid = user.attrclass(:gid).new(:resource => @resource)
183
- gid.should = "50"
184
- gid.should.must == 50
166
+ described_class.new(:name => 'foo', :gid => '50')[:gid].should == 50
185
167
  end
186
168
 
187
169
  it "should support GIDs specified as integers" do
188
- gid = user.attrclass(:gid).new(:resource => @resource)
189
- gid.should = 50
190
- gid.should.must == 50
170
+ described_class.new(:name => 'foo', :gid => 50)[:gid].should == 50
191
171
  end
192
172
 
193
173
  it "should support groups specified by name" do
194
- gid = user.attrclass(:gid).new(:resource => @resource)
195
- gid.should = "foo"
196
- gid.should.must == "foo"
174
+ described_class.new(:name => 'foo', :gid => 'foo')[:gid].should == 'foo'
197
175
  end
198
176
 
199
177
  describe "when testing whether in sync" do
200
- before do
201
- @gid = user.attrclass(:gid).new(:resource => @resource, :should => %w{foo bar})
202
- end
203
-
204
178
  it "should return true if no 'should' values are set" do
205
- @gid = user.attrclass(:gid).new(:resource => @resource)
206
-
207
- @gid.must be_safe_insync(500)
179
+ # this is currently not the case because gid has no default value, so we would never even
180
+ # call insync? on that property
181
+ if param = described_class.new(:name => 'foo').parameter(:gid)
182
+ param.must be_safe_insync(500)
183
+ end
208
184
  end
209
185
 
210
186
  it "should return true if any of the specified groups are equal to the current integer" do
211
187
  Puppet::Util.expects(:gid).with("foo").returns 300
212
188
  Puppet::Util.expects(:gid).with("bar").returns 500
213
-
214
- @gid.must be_safe_insync(500)
189
+ described_class.new(:name => 'baz', :gid => [ 'foo', 'bar' ]).parameter(:gid).must be_safe_insync(500)
215
190
  end
216
191
 
217
192
  it "should return false if none of the specified groups are equal to the current integer" do
218
193
  Puppet::Util.expects(:gid).with("foo").returns 300
219
194
  Puppet::Util.expects(:gid).with("bar").returns 500
220
-
221
- @gid.should_not be_safe_insync(700)
195
+ described_class.new(:name => 'baz', :gid => [ 'foo', 'bar' ]).parameter(:gid).must_not be_safe_insync(700)
222
196
  end
223
197
  end
224
198
 
225
199
  describe "when syncing" do
226
- before do
227
- @gid = user.attrclass(:gid).new(:resource => @resource, :should => %w{foo bar})
228
- end
229
-
230
200
  it "should use the first found, specified group as the desired value and send it to the provider" do
231
201
  Puppet::Util.expects(:gid).with("foo").returns nil
232
202
  Puppet::Util.expects(:gid).with("bar").returns 500
233
203
 
234
- @provider.expects(:gid=).with 500
204
+ @provider = @provider_class.new(:name => 'foo')
205
+ resource = described_class.new(:name => 'foo', :provider => @provider, :gid => [ 'foo', 'bar' ])
235
206
 
236
- @gid.sync
207
+ @provider.expects(:gid=).with 500
208
+ resource.parameter(:gid).sync
237
209
  end
238
210
  end
239
211
  end
240
212
 
241
- describe "when managing expiry" do
242
- before do
243
- @expiry = user.attrclass(:expiry).new(:resource => @resource)
213
+ describe "when managing groups" do
214
+ it "should support a singe group" do
215
+ lambda { described_class.new(:name => 'foo', :groups => 'bar') }.should_not raise_error
244
216
  end
245
217
 
246
- it "should fail if given an invalid date" do
247
- lambda { @expiry.should = "200-20-20" }.should raise_error(Puppet::Error)
218
+ it "should support multiple groups as an array" do
219
+ lambda { described_class.new(:name => 'foo', :groups => [ 'bar' ]) }.should_not raise_error
220
+ lambda { described_class.new(:name => 'foo', :groups => [ 'bar', 'baz' ]) }.should_not raise_error
221
+ end
222
+
223
+ it "should not support a comma separated list" do
224
+ lambda { described_class.new(:name => 'foo', :groups => 'bar,baz') }.should raise_error(Puppet::Error, /Group names must be provided as an array/)
225
+ end
226
+
227
+ it "should not support an empty string" do
228
+ lambda { described_class.new(:name => 'foo', :groups => '') }.should raise_error(Puppet::Error, /Group names must not be empty/)
229
+ end
230
+
231
+ describe "when testing is in sync" do
232
+
233
+ before :each do
234
+ # the useradd provider uses a single string to represent groups and so does Puppet::Property::List when converting to should values
235
+ @provider = @provider_class.new(:name => 'foo', :groups => 'a,b,e,f')
236
+ end
237
+
238
+ it "should not care about order" do
239
+ @property = described_class.new(:name => 'foo', :groups => [ 'a', 'c', 'b' ]).property(:groups)
240
+ @property.must be_safe_insync([ 'a', 'b', 'c' ])
241
+ @property.must be_safe_insync([ 'a', 'c', 'b' ])
242
+ @property.must be_safe_insync([ 'b', 'a', 'c' ])
243
+ @property.must be_safe_insync([ 'b', 'c', 'a' ])
244
+ @property.must be_safe_insync([ 'c', 'a', 'b' ])
245
+ @property.must be_safe_insync([ 'c', 'b', 'a' ])
246
+ end
247
+
248
+ it "should merge current value and desired value if membership minimal" do
249
+ @instance = described_class.new(:name => 'foo', :groups => [ 'a', 'c', 'b' ], :provider => @provider)
250
+ @instance[:membership] = :minimum
251
+ @instance[:groups].should == 'a,b,c,e,f'
252
+ end
253
+
254
+ it "should not treat a subset of groups insync if membership inclusive" do
255
+ @instance = described_class.new(:name => 'foo', :groups => [ 'a', 'c', 'b' ], :provider => @provider)
256
+ @instance[:membership] = :inclusive
257
+ @instance[:groups].should == 'a,b,c'
258
+ end
248
259
  end
249
260
  end
250
261
 
251
- describe "when managing minimum password age" do
252
- before do
253
- @age = user.attrclass(:password_min_age).new(:resource => @resource)
262
+
263
+ describe "when managing expiry" do
264
+ it "should fail if given an invalid date" do
265
+ lambda { described_class.new(:name => 'foo', :expiry => "200-20-20") }.should raise_error(Puppet::Error, /Expiry dates must be YYYY-MM-DD/)
254
266
  end
267
+ end
255
268
 
269
+ describe "when managing minimum password age" do
256
270
  it "should accept a negative minimum age" do
257
- expect { @age.should = -1 }.should_not raise_error
271
+ expect { described_class.new(:name => 'foo', :password_min_age => '-1') }.should_not raise_error
258
272
  end
259
273
 
260
274
  it "should fail with an empty minimum age" do
261
- expect { @age.should = '' }.should raise_error(Puppet::Error)
275
+ expect { described_class.new(:name => 'foo', :password_min_age => '') }.should raise_error(Puppet::Error, /minimum age must be provided as a number/)
262
276
  end
263
277
  end
264
278
 
265
279
  describe "when managing maximum password age" do
266
- before do
267
- @age = user.attrclass(:password_max_age).new(:resource => @resource)
268
- end
269
-
270
280
  it "should accept a negative maximum age" do
271
- expect { @age.should = -1 }.should_not raise_error
281
+ expect { described_class.new(:name => 'foo', :password_max_age => '-1') }.should_not raise_error
272
282
  end
273
283
 
274
284
  it "should fail with an empty maximum age" do
275
- expect { @age.should = '' }.should raise_error(Puppet::Error)
285
+ expect { described_class.new(:name => 'foo', :password_max_age => '') }.should raise_error(Puppet::Error, /maximum age must be provided as a number/)
276
286
  end
277
287
  end
278
288
 
279
289
  describe "when managing passwords" do
280
290
  before do
281
- @password = user.attrclass(:password).new(:resource => @resource, :should => "mypass")
291
+ @password = described_class.new(:name => 'foo', :password => 'mypass').parameter(:password)
282
292
  end
283
293
 
284
294
  it "should not include the password in the change log when adding the password" do
@@ -298,38 +308,24 @@ describe user do
298
308
  end
299
309
 
300
310
  it "should fail if a ':' is included in the password" do
301
- lambda { @password.should = "some:thing" }.should raise_error(Puppet::Error)
311
+ lambda { described_class.new(:name => 'foo', :password => "some:thing") }.should raise_error(Puppet::Error, /Passwords cannot include ':'/)
302
312
  end
303
313
 
304
314
  it "should allow the value to be set to :absent" do
305
- lambda { @password.should = :absent }.should_not raise_error
315
+ lambda { described_class.new(:name => 'foo', :password => :absent) }.should_not raise_error
306
316
  end
307
317
  end
308
318
 
309
319
  describe "when manages_solaris_rbac is enabled" do
310
- before do
311
- @provider.stubs(:satisfies?).returns(false)
312
- @provider.expects(:satisfies?).with([:manages_solaris_rbac]).returns(true)
313
- end
314
-
315
320
  it "should support a :role value for ensure" do
316
- @ensure = user.attrclass(:ensure).new(:resource => @resource)
317
- lambda { @ensure.should = :role }.should_not raise_error
321
+ lambda { described_class.new(:name => 'foo', :ensure => :role) }.should_not raise_error
318
322
  end
319
323
  end
320
324
 
321
325
  describe "when user has roles" do
322
- before do
323
- # To test this feature, we have to support it.
324
- user.new(:name => "foo").provider.class.stubs(:feature?).returns(true)
325
- end
326
-
327
326
  it "should autorequire roles" do
328
- testuser = Puppet::Type.type(:user).new(:name => "testuser")
329
- testuser.provider.stubs(:send).with(:roles).returns("")
330
- testuser[:roles] = "testrole"
331
-
332
- testrole = Puppet::Type.type(:user).new(:name => "testrole")
327
+ testuser = described_class.new(:name => "testuser", :roles => ['testrole'] )
328
+ testrole = described_class.new(:name => "testrole")
333
329
 
334
330
  config = Puppet::Resource::Catalog.new :testing do |conf|
335
331
  [testuser, testrole].each { |resource| conf.add_resource resource }