puppet 7.8.0 → 7.9.0

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 (146) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +5 -5
  3. data/Gemfile.lock +9 -9
  4. data/README.md +4 -4
  5. data/ext/project_data.yaml +1 -0
  6. data/install.rb +0 -4
  7. data/lib/puppet.rb +3 -3
  8. data/lib/puppet/application/filebucket.rb +1 -0
  9. data/lib/puppet/application/resource.rb +15 -2
  10. data/lib/puppet/application/ssl.rb +1 -0
  11. data/lib/puppet/defaults.rb +7 -0
  12. data/lib/puppet/environments.rb +10 -0
  13. data/lib/puppet/face/help/action.erb +1 -0
  14. data/lib/puppet/face/help/face.erb +1 -0
  15. data/lib/puppet/face/node/clean.rb +1 -1
  16. data/lib/puppet/file_system/file_impl.rb +1 -1
  17. data/lib/puppet/file_system/windows.rb +2 -2
  18. data/lib/puppet/forge.rb +3 -3
  19. data/lib/puppet/forge/cache.rb +1 -1
  20. data/lib/puppet/functions/empty.rb +8 -0
  21. data/lib/puppet/functions/strftime.rb +1 -0
  22. data/lib/puppet/functions/unwrap.rb +17 -2
  23. data/lib/puppet/indirector/resource/ral.rb +6 -1
  24. data/lib/puppet/interface/documentation.rb +1 -0
  25. data/lib/puppet/module_tool/applications/installer.rb +4 -0
  26. data/lib/puppet/module_tool/errors/shared.rb +17 -0
  27. data/lib/puppet/module_tool/tar/mini.rb +1 -1
  28. data/lib/puppet/pops/types/type_mismatch_describer.rb +1 -1
  29. data/lib/puppet/provider/exec/posix.rb +16 -4
  30. data/lib/puppet/provider/package/pip.rb +15 -3
  31. data/lib/puppet/provider/package/windows.rb +14 -1
  32. data/lib/puppet/provider/package/windows/exe_package.rb +30 -1
  33. data/lib/puppet/provider/package/windows/package.rb +2 -1
  34. data/lib/puppet/provider/parsedfile.rb +3 -0
  35. data/lib/puppet/resource/type_collection.rb +2 -0
  36. data/lib/puppet/settings.rb +30 -7
  37. data/lib/puppet/settings/config_file.rb +1 -8
  38. data/lib/puppet/settings/value_translator.rb +0 -1
  39. data/lib/puppet/type/exec.rb +16 -3
  40. data/lib/puppet/type/file/mode.rb +6 -0
  41. data/lib/puppet/type/tidy.rb +1 -1
  42. data/lib/puppet/type/user.rb +1 -1
  43. data/lib/puppet/util/monkey_patches.rb +2 -17
  44. data/lib/puppet/util/symbolic_file_mode.rb +29 -17
  45. data/lib/puppet/util/windows/sid.rb +3 -1
  46. data/lib/puppet/version.rb +1 -1
  47. data/lib/puppet/x509/cert_provider.rb +3 -21
  48. data/locales/puppet.pot +207 -171
  49. data/man/man5/puppet.conf.5 +2 -2
  50. data/man/man8/puppet-agent.8 +1 -1
  51. data/man/man8/puppet-apply.8 +1 -1
  52. data/man/man8/puppet-catalog.8 +9 -9
  53. data/man/man8/puppet-config.8 +1 -1
  54. data/man/man8/puppet-describe.8 +1 -1
  55. data/man/man8/puppet-device.8 +1 -1
  56. data/man/man8/puppet-doc.8 +1 -1
  57. data/man/man8/puppet-epp.8 +1 -1
  58. data/man/man8/puppet-facts.8 +7 -7
  59. data/man/man8/puppet-filebucket.8 +1 -1
  60. data/man/man8/puppet-generate.8 +1 -1
  61. data/man/man8/puppet-help.8 +1 -1
  62. data/man/man8/puppet-lookup.8 +1 -1
  63. data/man/man8/puppet-module.8 +1 -1
  64. data/man/man8/puppet-node.8 +5 -5
  65. data/man/man8/puppet-parser.8 +1 -1
  66. data/man/man8/puppet-plugin.8 +1 -1
  67. data/man/man8/puppet-report.8 +5 -5
  68. data/man/man8/puppet-resource.8 +1 -1
  69. data/man/man8/puppet-script.8 +1 -1
  70. data/man/man8/puppet-ssl.8 +1 -1
  71. data/man/man8/puppet.8 +2 -2
  72. data/spec/fixtures/ssl/127.0.0.1-key.pem +106 -106
  73. data/spec/fixtures/ssl/127.0.0.1.pem +48 -48
  74. data/spec/fixtures/ssl/bad-basic-constraints.pem +54 -54
  75. data/spec/fixtures/ssl/bad-int-basic-constraints.pem +51 -51
  76. data/spec/fixtures/ssl/ca.pem +52 -52
  77. data/spec/fixtures/ssl/crl.pem +25 -25
  78. data/spec/fixtures/ssl/ec-key-openssl.pem +8 -0
  79. data/spec/fixtures/ssl/ec-key-pk8.pem +5 -0
  80. data/spec/fixtures/ssl/ec-key.pem +11 -11
  81. data/spec/fixtures/ssl/ec.pem +32 -32
  82. data/spec/fixtures/ssl/encrypted-ec-key.pem +12 -12
  83. data/spec/fixtures/ssl/encrypted-key.pem +107 -107
  84. data/spec/fixtures/ssl/intermediate-agent-crl.pem +25 -25
  85. data/spec/fixtures/ssl/intermediate-agent.pem +54 -54
  86. data/spec/fixtures/ssl/intermediate-crl.pem +28 -28
  87. data/spec/fixtures/ssl/intermediate.pem +51 -51
  88. data/spec/fixtures/ssl/oid-key.pem +117 -0
  89. data/spec/fixtures/ssl/oid.pem +69 -0
  90. data/spec/fixtures/ssl/pluto-key.pem +106 -106
  91. data/spec/fixtures/ssl/pluto.pem +50 -50
  92. data/spec/fixtures/ssl/request-key.pem +106 -106
  93. data/spec/fixtures/ssl/request.pem +45 -45
  94. data/spec/fixtures/ssl/revoked-key.pem +106 -106
  95. data/spec/fixtures/ssl/revoked.pem +49 -49
  96. data/spec/fixtures/ssl/signed-key.pem +106 -106
  97. data/spec/fixtures/ssl/signed.pem +47 -47
  98. data/spec/fixtures/ssl/tampered-cert.pem +49 -49
  99. data/spec/fixtures/ssl/tampered-csr.pem +45 -45
  100. data/spec/fixtures/ssl/trusted_oid_mapping.yaml +5 -0
  101. data/spec/fixtures/ssl/unknown-127.0.0.1-key.pem +106 -106
  102. data/spec/fixtures/ssl/unknown-127.0.0.1.pem +48 -48
  103. data/spec/fixtures/ssl/unknown-ca-key.pem +106 -106
  104. data/spec/fixtures/ssl/unknown-ca.pem +52 -52
  105. data/spec/integration/application/filebucket_spec.rb +11 -0
  106. data/spec/integration/application/module_spec.rb +21 -0
  107. data/spec/integration/application/resource_spec.rb +35 -1
  108. data/spec/integration/application/ssl_spec.rb +20 -0
  109. data/spec/integration/defaults_spec.rb +5 -0
  110. data/spec/integration/environments/settings_interpolation_spec.rb +0 -4
  111. data/spec/integration/indirector/facts/facter_spec.rb +90 -36
  112. data/spec/integration/type/exec_spec.rb +70 -45
  113. data/spec/lib/puppet/test_ca.rb +5 -0
  114. data/spec/lib/puppet_spec/settings.rb +1 -0
  115. data/spec/unit/environments_spec.rb +35 -0
  116. data/spec/unit/file_system_spec.rb +6 -0
  117. data/spec/unit/functions/assert_type_spec.rb +1 -1
  118. data/spec/unit/functions/empty_spec.rb +10 -0
  119. data/spec/unit/functions/lookup_spec.rb +23 -0
  120. data/spec/unit/functions/unwrap_spec.rb +8 -0
  121. data/spec/unit/functions4_spec.rb +2 -2
  122. data/spec/unit/indirector/resource/ral_spec.rb +40 -75
  123. data/spec/unit/module_tool/applications/installer_spec.rb +13 -2
  124. data/spec/unit/parser/compiler_spec.rb +29 -0
  125. data/spec/unit/parser/templatewrapper_spec.rb +12 -2
  126. data/spec/unit/pops/loaders/dependency_loader_spec.rb +0 -9
  127. data/spec/unit/pops/parser/lexer2_spec.rb +0 -4
  128. data/spec/unit/provider/package/pip_spec.rb +37 -0
  129. data/spec/unit/provider/package/windows/exe_package_spec.rb +17 -0
  130. data/spec/unit/provider/parsedfile_spec.rb +10 -0
  131. data/spec/unit/resource/type_collection_spec.rb +16 -0
  132. data/spec/unit/resource/type_spec.rb +2 -2
  133. data/spec/unit/settings/config_file_spec.rb +1 -11
  134. data/spec/unit/settings/value_translator_spec.rb +4 -5
  135. data/spec/unit/settings_spec.rb +120 -79
  136. data/spec/unit/ssl/ssl_provider_spec.rb +18 -16
  137. data/spec/unit/type/exec_spec.rb +76 -29
  138. data/spec/unit/type/file/source_spec.rb +4 -4
  139. data/spec/unit/type/tidy_spec.rb +7 -0
  140. data/spec/unit/util/ldap/connection_spec.rb +10 -10
  141. data/spec/unit/util/ldap/manager_spec.rb +2 -2
  142. data/spec/unit/util/windows/sid_spec.rb +39 -4
  143. data/spec/unit/util_spec.rb +1 -3
  144. data/spec/unit/x509/cert_provider_spec.rb +9 -1
  145. data/tasks/generate_cert_fixtures.rake +10 -1
  146. metadata +16 -3
@@ -290,6 +290,12 @@ describe "Puppet::FileSystem" do
290
290
  expect(Puppet::FileSystem.read_preserve_line_endings(file)).to eq("file content \r\nsecond line \n")
291
291
  end
292
292
  end
293
+
294
+ it "should ignore leading BOM" do
295
+ with_file_content("\uFEFFfile content \n") do |file|
296
+ expect(Puppet::FileSystem.read_preserve_line_endings(file)).to eq("file content \n")
297
+ end
298
+ end
293
299
  end
294
300
 
295
301
  context "read without an encoding specified" do
@@ -28,7 +28,7 @@ describe 'the assert_type function' do
28
28
  it 'checks that first argument is a type' do
29
29
  expect do
30
30
  func.call({}, 10, 10)
31
- end.to raise_error(ArgumentError, "'assert_type' expects one of:
31
+ end.to raise_error(ArgumentError, "The function 'assert_type' was called with arguments it does not accept. It expects one of:
32
32
  (Type type, Any value, Callable[Type, Type] block?)
33
33
  rejected: parameter 'type' expects a Type value, got Integer
34
34
  (String type_string, Any value, Callable[Type, Type] block?)
@@ -56,6 +56,16 @@ describe 'the empty function' do
56
56
  end
57
57
  end
58
58
 
59
+ context 'for a sensitive string it' do
60
+ it 'returns true when empty' do
61
+ expect(compile_to_catalog("notify { String(empty(Sensitive(''))): }")).to have_resource('Notify[true]')
62
+ end
63
+
64
+ it 'returns false when not empty' do
65
+ expect(compile_to_catalog("notify { String(empty(Sensitive(' '))): }")).to have_resource('Notify[false]')
66
+ end
67
+ end
68
+
59
69
  context 'for a binary it' do
60
70
  it 'returns true when empty' do
61
71
  expect(compile_to_catalog("notify { String(empty(Binary(''))): }")).to have_resource('Notify[true]')
@@ -3303,6 +3303,29 @@ describe "The lookup function" do
3303
3303
  end
3304
3304
  end
3305
3305
 
3306
+ context 'using options containing intepolated paths to the key pair' do
3307
+ let(:scope_additions) { { 'priv_path' => private_key_path, 'pub_path' => public_key_path } }
3308
+
3309
+ let(:hiera_yaml) do
3310
+ <<-YAML.unindent
3311
+ version: 5
3312
+ defaults:
3313
+ datadir: #{code_dir}/hieradata
3314
+ hierarchy:
3315
+ - name: "secret data"
3316
+ lookup_key: eyaml_lookup_key
3317
+ path: common.eyaml
3318
+ options:
3319
+ pkcs7_private_key: "%{priv_path}"
3320
+ pkcs7_public_key: "%{pub_path}"
3321
+ YAML
3322
+ end
3323
+
3324
+ it 'finds data in the global layer' do
3325
+ expect(lookup('a')).to eql("Encrypted value 'a' (from global)")
3326
+ end
3327
+ end
3328
+
3306
3329
  context 'with special extension declared in options' do
3307
3330
  let(:environment_files) { {} }
3308
3331
  let(:hiera_yaml) do
@@ -15,6 +15,14 @@ describe 'the unwrap function' do
15
15
  expect(eval_and_collect_notices(code)).to eq(['unwrapped value is 12345'])
16
16
  end
17
17
 
18
+ it 'just returns a non-sensitive value' do
19
+ code = <<-CODE
20
+ $non_sensitive = "12345"
21
+ notice("value is still ${non_sensitive.unwrap}")
22
+ CODE
23
+ expect(eval_and_collect_notices(code)).to eq(['value is still 12345'])
24
+ end
25
+
18
26
  it 'unwraps a sensitive value when given a code block' do
19
27
  code = <<-CODE
20
28
  $sensitive = Sensitive.new("12345")
@@ -169,7 +169,7 @@ describe 'the 4x function api' do
169
169
  expect(func.is_a?(Puppet::Functions::Function)).to be_truthy
170
170
  expect do
171
171
  func.call({}, 3, 10, 3, "4")
172
- end.to raise_error(ArgumentError, "'min' expects one of:
172
+ end.to raise_error(ArgumentError, "The function 'min' was called with arguments it does not accept. It expects one of:
173
173
  (Numeric x, Numeric y, Numeric a?, Numeric b?, Numeric c*)
174
174
  rejected: parameter 'b' expects a Numeric value, got String
175
175
  (String x, String y, String a+)
@@ -240,7 +240,7 @@ describe 'the 4x function api' do
240
240
  expect(func.is_a?(Puppet::Functions::Function)).to be_truthy
241
241
  expect do
242
242
  func.call({}, 10, '20')
243
- end.to raise_error(ArgumentError, "'min' expects one of:
243
+ end.to raise_error(ArgumentError, "The function 'min' was called with arguments it does not accept. It expects one of:
244
244
  (Numeric a, Numeric b)
245
245
  rejected: parameter 'b' expects a Numeric value, got String
246
246
  (String s1, String s2)
@@ -1,120 +1,85 @@
1
1
  require 'spec_helper'
2
2
  require 'puppet/indirector/resource/ral'
3
3
 
4
- describe "Puppet::Resource::Ral" do
4
+ describe Puppet::Resource::Ral do
5
+ let(:my_instance) { Puppet::Type.type(:user).new(:name => "root") }
6
+ let(:wrong_instance) { Puppet::Type.type(:user).new(:name => "bob")}
7
+
8
+ def stub_retrieve(*instances)
9
+ instances.each do |i|
10
+ allow(i).to receive(:retrieve).and_return(Puppet::Resource.new(i, nil))
11
+ end
12
+ end
13
+
14
+ before do
15
+ described_class.indirection.terminus_class = :ral
16
+
17
+ # make sure we don't try to retrieve current state
18
+ allow_any_instance_of(Puppet::Type.type(:user)).to receive(:retrieve).never
19
+ stub_retrieve(my_instance, wrong_instance)
20
+ end
21
+
5
22
  it "disallows remote requests" do
6
23
  expect(Puppet::Resource::Ral.new.allow_remote_requests?).to eq(false)
7
24
  end
8
25
 
9
26
  describe "find" do
10
- before do
11
- @request = double('request', :key => "user/root")
12
- end
13
-
14
27
  it "should find an existing instance" do
15
- my_resource = double("my user resource")
28
+ allow(Puppet::Type.type(:user)).to receive(:instances).and_return([ wrong_instance, my_instance, wrong_instance ])
16
29
 
17
- wrong_instance = double("wrong user", :name => "bob")
18
- my_instance = double("my user", :name => "root", :to_resource => my_resource)
19
-
20
- expect(Puppet::Type.type(:user)).to receive(:instances).and_return([ wrong_instance, my_instance, wrong_instance ])
21
- expect(Puppet::Resource::Ral.new.find(@request)).to eq(my_resource)
30
+ actual_resource = described_class.indirection.find('user/root')
31
+ expect(actual_resource.name).to eq('User/root')
22
32
  end
23
33
 
24
34
  it "should produce Puppet::Error instead of ArgumentError" do
25
- @bad_request = double('thiswillcauseanerror', :key => "thiswill/causeanerror")
26
- expect{Puppet::Resource::Ral.new.find(@bad_request)}.to raise_error(Puppet::Error)
35
+ expect{described_class.indirection.find('thiswill/causeanerror')}.to raise_error(Puppet::Error)
27
36
  end
28
37
 
29
38
  it "if there is no instance, it should create one" do
30
- wrong_instance = double("wrong user", :name => "bob")
31
- root = double("Root User")
32
- root_resource = double("Root Resource")
33
-
34
- expect(Puppet::Type.type(:user)).to receive(:instances).and_return([ wrong_instance, wrong_instance ])
35
- expect(Puppet::Type.type(:user)).to receive(:new).with(hash_including(name: "root")).and_return(root)
36
- expect(root).to receive(:to_resource).and_return(root_resource)
37
-
38
- result = Puppet::Resource::Ral.new.find(@request)
39
+ allow(Puppet::Type.type(:user)).to receive(:instances).and_return([wrong_instance])
39
40
 
40
- expect(result).to eq(root_resource)
41
+ expect(Puppet::Type.type(:user)).to receive(:new).with(hash_including(name: "root")).and_return(my_instance)
42
+ expect(described_class.indirection.find('user/root')).to be
41
43
  end
42
44
  end
43
45
 
44
46
  describe "search" do
45
- before do
46
- @request = double('request', :key => "user/", :options => {})
47
- end
48
-
49
47
  it "should convert ral resources into regular resources" do
50
- my_resource = double("my user resource", :title => "my user resource")
51
- my_instance = double("my user", :name => "root", :to_resource => my_resource)
48
+ allow(Puppet::Type.type(:user)).to receive(:instances).and_return([ my_instance ])
52
49
 
53
- expect(Puppet::Type.type(:user)).to receive(:instances).and_return([ my_instance ])
54
- expect(Puppet::Resource::Ral.new.search(@request)).to eq([my_resource])
50
+ actual = described_class.indirection.search('user')
51
+ expect(actual).to contain_exactly(an_instance_of(Puppet::Resource))
55
52
  end
56
53
 
57
54
  it "should filter results by name if there's a name in the key" do
58
- my_resource = double("my user resource", title: "my user resource")
59
- allow(my_resource).to receive(:to_resource).and_return(my_resource)
60
- allow(my_resource).to receive(:[]).with(:name).and_return("root")
61
-
62
- wrong_resource = double("wrong resource")
63
- allow(wrong_resource).to receive(:to_resource).and_return(wrong_resource)
64
- allow(wrong_resource).to receive(:[]).with(:name).and_return("bad")
55
+ allow(Puppet::Type.type(:user)).to receive(:instances).and_return([ my_instance, wrong_instance ])
65
56
 
66
- my_instance = double("my user", :to_resource => my_resource)
67
- wrong_instance = double("wrong user", :to_resource => wrong_resource)
68
-
69
- @request = double('request', :key => "user/root", :options => {})
70
-
71
- expect(Puppet::Type.type(:user)).to receive(:instances).and_return([ my_instance, wrong_instance ])
72
- expect(Puppet::Resource::Ral.new.search(@request)).to eq([my_resource])
57
+ actual = described_class.indirection.search('user/root')
58
+ expect(actual).to contain_exactly(an_object_having_attributes(name: 'User/root'))
73
59
  end
74
60
 
75
61
  it "should filter results by query parameters" do
76
- wrong_resource = double("my user resource", title: "my user resource")
77
- allow(wrong_resource).to receive(:to_resource).and_return(wrong_resource)
78
- allow(wrong_resource).to receive(:[]).with(:name).and_return("root")
79
-
80
- my_resource = double("wrong resource", title: "wrong resource")
81
- allow(my_resource).to receive(:to_resource).and_return(my_resource)
82
- allow(my_resource).to receive(:[]).with(:name).and_return("bob")
62
+ allow(Puppet::Type.type(:user)).to receive(:instances).and_return([ my_instance, wrong_instance ])
83
63
 
84
- my_instance = double("my user", :to_resource => my_resource)
85
- wrong_instance = double("wrong user", :to_resource => wrong_resource)
86
-
87
- @request = double('request', :key => "user/", :options => {:name => "bob"})
88
-
89
- expect(Puppet::Type.type(:user)).to receive(:instances).and_return([ my_instance, wrong_instance ])
90
- expect(Puppet::Resource::Ral.new.search(@request)).to eq([my_resource])
64
+ actual = described_class.indirection.search('user', name: 'bob')
65
+ expect(actual).to contain_exactly(an_object_having_attributes(name: 'User/bob'))
91
66
  end
92
67
 
93
68
  it "should return sorted results" do
94
- a_resource = double("alice resource")
95
- allow(a_resource).to receive(:to_resource).and_return(a_resource)
96
- allow(a_resource).to receive(:title).and_return("alice")
97
-
98
- b_resource = double("bob resource")
99
- allow(b_resource).to receive(:to_resource).and_return(b_resource)
100
- allow(b_resource).to receive(:title).and_return("bob")
101
-
102
- a_instance = double("alice user", :to_resource => a_resource)
103
- b_instance = double("bob user", :to_resource => b_resource)
104
-
105
- @request = double('request', :key => "user/", :options => {})
69
+ a_instance = Puppet::Type.type(:user).new(:name => "alice")
70
+ b_instance = Puppet::Type.type(:user).new(:name => "bob")
71
+ stub_retrieve(a_instance, b_instance)
72
+ allow(Puppet::Type.type(:user)).to receive(:instances).and_return([ b_instance, a_instance ])
106
73
 
107
- expect(Puppet::Type.type(:user)).to receive(:instances).and_return([ b_instance, a_instance ])
108
- expect(Puppet::Resource::Ral.new.search(@request)).to eq([a_resource, b_resource])
74
+ expect(described_class.indirection.search('user').map(&:title)).to eq(['alice', 'bob'])
109
75
  end
110
76
  end
111
77
 
112
78
  describe "save" do
113
79
  it "returns a report covering the application of the given resource to the system" do
114
80
  resource = Puppet::Resource.new(:notify, "the title")
115
- ral = Puppet::Resource::Ral.new
116
81
 
117
- applied_resource, report = ral.save(Puppet::Indirector::Request.new(:ral, :save, 'testing', resource, :environment => Puppet::Node::Environment.remote(:testing)))
82
+ applied_resource, report = described_class.indirection.save(resource, nil, environment: Puppet::Node::Environment.remote(:testing))
118
83
 
119
84
  expect(applied_resource.title).to eq("the title")
120
85
  expect(report.environment).to eq("testing")
@@ -34,8 +34,7 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => RUBY_PLATFORM =
34
34
 
35
35
  if Puppet::Util::Platform.windows?
36
36
  before :each do
37
- allow(Puppet.settings).to receive(:[])
38
- allow(Puppet.settings).to receive(:[]).with(:module_working_dir).and_return(Dir.mktmpdir('installertmp'))
37
+ Puppet[:module_working_dir] = tmpdir('module_tool_install').gsub('/', '\\')
39
38
  end
40
39
  end
41
40
 
@@ -66,6 +65,18 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => RUBY_PLATFORM =
66
65
  graph_should_include 'pmtacceptance-stdlib', nil => v('4.1.0')
67
66
  end
68
67
 
68
+ it 'reports a meaningful error if the name is invalid' do
69
+ app = installer('ntp', install_dir, options)
70
+ results = app.run
71
+ expect(results).to include :result => :failure
72
+ expect(results[:error][:oneline]).to eq("Could not install 'ntp', did you mean 'puppetlabs-ntp'?")
73
+ expect(results[:error][:multiline]).to eq(<<~END.chomp)
74
+ Could not install module 'ntp'
75
+ The name 'ntp' is invalid
76
+ Did you mean `puppet module install puppetlabs-ntp`?
77
+ END
78
+ end
79
+
69
80
  context 'with a tarball file' do
70
81
  let(:module) { fixtures('stdlib.tgz') }
71
82
 
@@ -862,6 +862,35 @@ describe Puppet::Parser::Compiler do
862
862
 
863
863
  expect(catalog.resource('Class', 'Something')).not_to be_nil
864
864
  end
865
+
866
+ it "raises if the class name is the same as the node definition" do
867
+ name = node.name
868
+ node.classes = [name]
869
+
870
+ expect {
871
+ compile_to_catalog(<<-MANIFEST, node)
872
+ class #{name} {}
873
+ node #{name} {
874
+ include #{name}
875
+ }
876
+ MANIFEST
877
+ }.to raise_error(Puppet::Error, /Class '#{name}' is already defined \(line: 1\); cannot be redefined as a node \(line: 2\) on node #{name}/)
878
+ end
879
+
880
+ it "evaluates the class if the node definition uses a regexp" do
881
+ name = node.name
882
+ node.classes = [name]
883
+
884
+ catalog = compile_to_catalog(<<-MANIFEST, node)
885
+ class #{name} {}
886
+ node /#{name}/ {
887
+ include #{name}
888
+ }
889
+ MANIFEST
890
+
891
+ expect(@logs).to be_empty
892
+ expect(catalog.resource('Class', node.name.capitalize)).to_not be_nil
893
+ end
865
894
  end
866
895
 
867
896
  it "should fail if the class doesn't exist" do
@@ -2,6 +2,8 @@ require 'spec_helper'
2
2
  require 'puppet/parser/templatewrapper'
3
3
 
4
4
  describe Puppet::Parser::TemplateWrapper do
5
+ include PuppetSpec::Files
6
+
5
7
  let(:known_resource_types) { Puppet::Resource::TypeCollection.new("env") }
6
8
  let(:scope) do
7
9
  compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
@@ -41,6 +43,13 @@ describe Puppet::Parser::TemplateWrapper do
41
43
  expect(tw.result).to eq(full_file_name)
42
44
  end
43
45
 
46
+ it "ignores a leading BOM" do
47
+ full_file_name = given_a_template_file("bom_template", "\uFEFF<%= file %>")
48
+
49
+ tw.file = "bom_template"
50
+ expect(tw.result).to eq(full_file_name)
51
+ end
52
+
44
53
  it "evaluates a given string as a template" do
45
54
  expect(tw.result("template contents")).to eql("template contents")
46
55
  end
@@ -90,11 +99,12 @@ describe Puppet::Parser::TemplateWrapper do
90
99
  end
91
100
 
92
101
  def given_a_template_file(name, contents)
93
- full_name = "/full/path/to/#{name}"
102
+ full_name = tmpfile("template_#{name}")
103
+ File.binwrite(full_name, contents)
104
+
94
105
  allow(Puppet::Parser::Files).to receive(:find_template).
95
106
  with(name, anything()).
96
107
  and_return(full_name)
97
- allow(Puppet::FileSystem).to receive(:read_preserve_line_endings).with(full_name).and_return(contents)
98
108
 
99
109
  full_name
100
110
  end
@@ -84,10 +84,6 @@ Puppet::Functions.create_function('testmodule::foo') {
84
84
 
85
85
  context 'when loading files from disk' do
86
86
  it 'should always read files as UTF-8' do
87
- if Puppet::Util::Platform.windows? && Encoding.default_external == Encoding::UTF_8
88
- raise 'This test must be run in a codepage other than 65001 to validate behavior'
89
- end
90
-
91
87
  module_dir = dir_containing('testmodule', {
92
88
  'lib' => { 'puppet' => { 'functions' => { 'testmodule' => {
93
89
  'foo.rb' => code_utf8
@@ -101,11 +97,6 @@ Puppet::Functions.create_function('testmodule::foo') {
101
97
 
102
98
  it 'currently ignores the UTF-8 BOM (Byte Order Mark) when loading module files' do
103
99
  bom = "\uFEFF"
104
-
105
- if Puppet::Util::Platform.windows? && Encoding.default_external == Encoding::UTF_8
106
- raise 'This test must be run in a codepage other than 65001 to validate behavior'
107
- end
108
-
109
100
  module_dir = dir_containing('testmodule', {
110
101
  'lib' => { 'puppet' => { 'functions' => { 'testmodule' => {
111
102
  'foo.rb' => "#{bom}#{code_utf8}"
@@ -918,10 +918,6 @@ describe Puppet::Pops::Parser::Lexer2 do
918
918
 
919
919
  context 'when lexing files from disk' do
920
920
  it 'should always read files as UTF-8' do
921
- if Puppet::Util::Platform.windows? && Encoding.default_external == Encoding::UTF_8
922
- raise 'This test must be run in a codepage other than 65001 to validate behavior'
923
- end
924
-
925
921
  manifest_code = "notify { '#{rune_utf8}': }"
926
922
  manifest = file_containing('manifest.pp', manifest_code)
927
923
  lexed_file = described_class.new.lex_file(manifest)
@@ -266,6 +266,43 @@ describe Puppet::Type.type(:package).provider(:pip) do
266
266
  let(:pip_version) { '1.5.4' }
267
267
  let(:pip_path) { '/fake/bin/pip' }
268
268
 
269
+ context "with pip version >= 20.3 and < 21.1" do
270
+ let(:pip_version) { '20.3.1' }
271
+ let(:pip_path) { '/fake/bin/pip' }
272
+
273
+ it "should use legacy-resolver argument" do
274
+ p = StringIO.new(
275
+ <<-EOS
276
+ Collecting real-package==versionplease
277
+ Could not find a version that satisfies the requirement real-package==versionplease (from versions: 1.1.3, 1.0, 1.9b1)
278
+ No matching distribution found for real-package==versionplease
279
+ EOS
280
+ )
281
+ expect(Puppet::Util::Execution).to receive(:execpipe).with(["/fake/bin/pip", "install", "real_package==versionplease",
282
+ "--use-deprecated=legacy-resolver"]).and_yield(p).once
283
+ @resource[:name] = "real_package"
284
+ @provider.latest
285
+ end
286
+ end
287
+
288
+ context "with pip version >= 21.1" do
289
+ let(:pip_version) { '21.1' }
290
+ let(:pip_path) { '/fake/bin/pip' }
291
+
292
+ it "should not use legacy-resolver argument" do
293
+ p = StringIO.new(
294
+ <<-EOS
295
+ Collecting real-package==versionplease
296
+ Could not find a version that satisfies the requirement real-package==versionplease (from versions: 1.1.3, 1.0, 1.9b1)
297
+ No matching distribution found for real-package==versionplease
298
+ EOS
299
+ )
300
+ expect(Puppet::Util::Execution).to receive(:execpipe).with(["/fake/bin/pip", "install", "real_package==versionplease"]).and_yield(p).once
301
+ @resource[:name] = "real_package"
302
+ @provider.latest
303
+ end
304
+ end
305
+
269
306
  it "should find a version number for real_package" do
270
307
  p = StringIO.new(
271
308
  <<-EOS