puppet 7.3.0 → 7.4.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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +9 -9
  3. data/ext/build_defaults.yaml +0 -1
  4. data/lib/puppet/face/facts.rb +16 -6
  5. data/lib/puppet/ffi/windows/constants.rb +1 -1
  6. data/lib/puppet/indirector/facts/facter.rb +1 -0
  7. data/lib/puppet/property/list.rb +1 -1
  8. data/lib/puppet/provider/group/groupadd.rb +13 -8
  9. data/lib/puppet/provider/package/apt.rb +30 -2
  10. data/lib/puppet/provider/package/aptitude.rb +6 -0
  11. data/lib/puppet/provider/service/debian.rb +2 -0
  12. data/lib/puppet/provider/user/useradd.rb +55 -8
  13. data/lib/puppet/type/package.rb +3 -3
  14. data/lib/puppet/version.rb +1 -1
  15. data/locales/puppet.pot +27 -23
  16. data/man/man5/puppet.conf.5 +2 -2
  17. data/man/man8/puppet-agent.8 +1 -1
  18. data/man/man8/puppet-apply.8 +1 -1
  19. data/man/man8/puppet-catalog.8 +1 -1
  20. data/man/man8/puppet-config.8 +1 -1
  21. data/man/man8/puppet-describe.8 +1 -1
  22. data/man/man8/puppet-device.8 +1 -1
  23. data/man/man8/puppet-doc.8 +1 -1
  24. data/man/man8/puppet-epp.8 +1 -1
  25. data/man/man8/puppet-facts.8 +5 -2
  26. data/man/man8/puppet-filebucket.8 +1 -1
  27. data/man/man8/puppet-generate.8 +1 -1
  28. data/man/man8/puppet-help.8 +1 -1
  29. data/man/man8/puppet-lookup.8 +1 -1
  30. data/man/man8/puppet-module.8 +1 -1
  31. data/man/man8/puppet-node.8 +1 -1
  32. data/man/man8/puppet-parser.8 +1 -1
  33. data/man/man8/puppet-plugin.8 +1 -1
  34. data/man/man8/puppet-report.8 +1 -1
  35. data/man/man8/puppet-resource.8 +1 -1
  36. data/man/man8/puppet-script.8 +1 -1
  37. data/man/man8/puppet-ssl.8 +1 -1
  38. data/man/man8/puppet.8 +2 -2
  39. data/spec/integration/application/agent_spec.rb +33 -0
  40. data/spec/unit/application/facts_spec.rb +55 -4
  41. data/spec/unit/indirector/facts/facter_spec.rb +9 -0
  42. data/spec/unit/provider/group/groupadd_spec.rb +5 -2
  43. data/spec/unit/provider/package/apt_spec.rb +24 -15
  44. data/spec/unit/provider/package/aptitude_spec.rb +1 -1
  45. data/spec/unit/provider/user/useradd_spec.rb +55 -3
  46. data/spec/unit/ssl/certificate_request_spec.rb +4 -10
  47. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6583e2420f7a36ea7119f415387e8f4dfa741e9537b7d17da02ad79a436c39f7
4
- data.tar.gz: 9804c7626d3fc6a771b837a03afe2efe04daf56a6ce94dd1263275c9d7cd3c5e
3
+ metadata.gz: f0f22910c91937d056ea9cf856bd6bd0dccb5cd87f91dfee3ee4fe7a4fa7173a
4
+ data.tar.gz: bbafd9dc102a1af3390d3c13499eb264d3de9aaab59f97f560f407fc3e608af3
5
5
  SHA512:
6
- metadata.gz: 14c7a341a6f9e4a4565738112d736ba5a9b5eca3f6c64441565dee5eddfcc7fc1eff8794e8983ebf64ac1cff489d00666c4f3998ca5970d096eba117d829def8
7
- data.tar.gz: '098227b0850062512d24aae0eeb6e5d31540029aa5d8418953a68597b46f8b278aad469263feee3ef059fcb5f1d6f1fc9dcb3a0b3810bf40c45a8680afd49f56'
6
+ metadata.gz: c051a9734e730355205789fa88d65e769086d3caa3fb3c76b9098e21aefa34df30bb577e7cfc7f1e4add4e43df1517188536b9c7d77b35d89a50d67c81cafa7e
7
+ data.tar.gz: 83244048f67693f29c058bf4b80c5037467a94a6a38d84f4838aa4eb451aefc1596d3d65889c7cdbe93a9e241d82c8c80ad4674e8de715a231ff07aa6ffebfd0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- puppet (7.3.0)
4
+ puppet (7.4.0)
5
5
  CFPropertyList (~> 2.2)
6
6
  concurrent-ruby (~> 1.0)
7
7
  deep_merge (~> 1.0)
@@ -20,16 +20,16 @@ GEM
20
20
  addressable (2.7.0)
21
21
  public_suffix (>= 2.0.2, < 5.0)
22
22
  artifactory (2.8.2)
23
- ast (2.4.1)
23
+ ast (2.4.2)
24
24
  coderay (1.1.3)
25
- concurrent-ruby (1.1.7)
25
+ concurrent-ruby (1.1.8)
26
26
  crack (0.4.5)
27
27
  rexml
28
28
  csv (3.1.5)
29
29
  deep_merge (1.2.1)
30
30
  diff-lcs (1.4.4)
31
31
  docopt (0.6.1)
32
- facter (4.0.49)
32
+ facter (4.0.50)
33
33
  hocon (~> 1.3)
34
34
  thor (>= 1.0.1, < 2.0)
35
35
  fast_gettext (1.1.2)
@@ -55,7 +55,7 @@ GEM
55
55
  memory_profiler (1.0.0)
56
56
  method_source (1.0.0)
57
57
  minitar (0.9)
58
- msgpack (1.3.3)
58
+ msgpack (1.4.2)
59
59
  multi_json (1.15.0)
60
60
  mustache (1.1.1)
61
61
  optimist (3.0.1)
@@ -102,10 +102,10 @@ GEM
102
102
  rspec-its (1.3.0)
103
103
  rspec-core (>= 3.0.0)
104
104
  rspec-expectations (>= 3.0.0)
105
- rspec-mocks (3.10.1)
105
+ rspec-mocks (3.10.2)
106
106
  diff-lcs (>= 1.2.0, < 2.0)
107
107
  rspec-support (~> 3.10.0)
108
- rspec-support (3.10.1)
108
+ rspec-support (3.10.2)
109
109
  rubocop (0.49.1)
110
110
  parallel (~> 1.10)
111
111
  parser (>= 2.3.3.1, < 3.0)
@@ -120,10 +120,10 @@ GEM
120
120
  scanf (1.0.0)
121
121
  semantic_puppet (1.0.3)
122
122
  text (1.3.1)
123
- thor (1.0.1)
123
+ thor (1.1.0)
124
124
  unicode-display_width (1.7.0)
125
125
  vcr (5.1.0)
126
- webmock (3.11.1)
126
+ webmock (3.11.2)
127
127
  addressable (>= 2.3.6)
128
128
  crack (>= 0.3.2)
129
129
  hashdiff (>= 0.4.0, < 2.0.0)
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  packager: 'puppetlabs'
3
- gpg_key: '7F438280EF8D349F'
4
3
 
5
4
  # These are the build targets used by the packaging repo. Uncomment to allow use.
6
5
  #final_mocks: 'pl-el-5-i386 pl-el-6-i386 pl-el-7-x86_64'
@@ -127,11 +127,15 @@ Puppet::Indirector::Face.define(:facts, '0.0.1') do
127
127
  option("--show-legacy") do
128
128
  summary _("Show legacy facts when querying all facts.")
129
129
  end
130
-
130
+
131
131
  option("--value-only") do
132
132
  summary _("Show only the value when the action is called with a single query")
133
133
  end
134
134
 
135
+ option("--timing") do
136
+ summary _("Show how much time it took to resolve each fact.")
137
+ end
138
+
135
139
  when_invoked do |*args|
136
140
  options = args.pop
137
141
 
@@ -147,17 +151,23 @@ Puppet::Indirector::Face.define(:facts, '0.0.1') do
147
151
  options[:resolve_options] = true
148
152
  result = Puppet::Node::Facts.indirection.find(Puppet.settings[:certname], options)
149
153
 
150
- facts = result.values
151
-
152
154
  if options[:value_only]
153
- facts.values.first
155
+ result.values.values.first
154
156
  else
155
- facts
157
+ result.values
156
158
  end
157
159
  end
158
160
 
159
161
  when_rendering :console do |result|
160
- Puppet::Util::Json.dump(result, :pretty => true)
162
+ # VALID_TYPES = [Integer, Float, TrueClass, FalseClass, NilClass, Symbol, String, Array, Hash].freeze
163
+ # from https://github.com/puppetlabs/facter/blob/4.0.49/lib/facter/custom_facts/util/normalization.rb#L8
164
+
165
+ case result
166
+ when Array, Hash
167
+ Puppet::Util::Json.dump(result, :pretty => true)
168
+ else # one of VALID_TYPES above
169
+ result
170
+ end
161
171
  end
162
172
  end
163
173
  end
@@ -375,7 +375,7 @@ module Puppet::FFI::Windows
375
375
  SERVICE_CONFIG_PRESHUTDOWN_INFO = 0x00000007
376
376
  SERVICE_CONFIG_TRIGGER_INFO = 0x00000008
377
377
  SERVICE_CONFIG_PREFERRED_NODE = 0x00000009
378
- SERVICE_CONFIG_LAUNCH_PROTECTED = 0x00000012
378
+ SERVICE_CONFIG_LAUNCH_PROTECTED = 0x0000000C
379
379
  SERVICE_NO_CHANGE = 0xffffffff
380
380
  SERVICE_CONFIG_TYPES = {
381
381
  SERVICE_CONFIG_DESCRIPTION => :SERVICE_CONFIG_DESCRIPTION,
@@ -103,6 +103,7 @@ class Puppet::Node::Facts::Facter < Puppet::Indirector::Code
103
103
  options_for_facter += " --show-legacy" if options[:show_legacy]
104
104
  options_for_facter += " --no-block" if options[:no_block] == false
105
105
  options_for_facter += " --no-cache" if options[:no_cache] == false
106
+ options_for_facter += " --timing" if options[:timing]
106
107
 
107
108
  Puppet::Node::Facts.new(request.key, Facter.resolve(options_for_facter))
108
109
  end
@@ -47,7 +47,7 @@ module Puppet
47
47
  #ok, some 'convention' if the list property is named groups, provider should implement a groups method
48
48
  tmp = provider.send(name) if provider
49
49
  if tmp && tmp != :absent
50
- return tmp.split(delimiter)
50
+ return tmp.instance_of?(Array) ? tmp : tmp.split(delimiter)
51
51
  else
52
52
  return :absent
53
53
  end
@@ -130,16 +130,21 @@ Puppet::Type.type(:group).provide :groupadd, :parent => Puppet::Provider::NameSe
130
130
  private
131
131
 
132
132
  def findgroup(key, value)
133
- group_file = "/etc/group"
133
+ group_file = '/etc/group'
134
134
  group_keys = [:group_name, :password, :gid, :user_list]
135
- index = group_keys.index(key)
136
- @group_content ||= File.read(group_file)
137
- @group_content.each_line do |line|
138
- group = line.split(":")
139
- if group[index] == value
140
- return Hash[group_keys.zip(group)]
135
+
136
+ unless @groups
137
+ unless Puppet::FileSystem.exist?(group_file)
138
+ raise Puppet::Error.new("Forcelocal set for group resource '#{resource[:name]}', but #{group_file} does not exist")
139
+ end
140
+
141
+ @groups = []
142
+ Puppet::FileSystem.each_line(group_file) do |line|
143
+ group = line.chomp.split(':')
144
+ @groups << Hash[group_keys.zip(group)]
141
145
  end
142
146
  end
143
- false
147
+
148
+ @groups.find { |param| param[key] == value } || false
144
149
  end
145
150
  end
@@ -42,7 +42,11 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
42
42
 
43
43
  def query
44
44
  hash = super
45
- hash[:mark] = :manual if aptmark('showmanual').split("\n").include?(@resource[:name])
45
+
46
+ if !%i(absent purged).include?(hash[:ensure]) && aptmark('showmanual', @resource[:name]).strip == @resource[:name]
47
+ hash[:mark] = :manual
48
+ end
49
+
46
50
  hash
47
51
  end
48
52
 
@@ -147,7 +151,13 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
147
151
  end
148
152
 
149
153
  cmd += install_options if @resource[:install_options]
150
- cmd << :install << str
154
+ cmd << :install
155
+
156
+ if source
157
+ cmd << source
158
+ else
159
+ cmd << str
160
+ end
151
161
 
152
162
  self.unhold if self.properties[:mark] == :hold
153
163
  begin
@@ -155,6 +165,18 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
155
165
  ensure
156
166
  self.hold if @resource[:mark] == :hold
157
167
  end
168
+
169
+ # If a source file was specified, we must make sure the expected version was installed from specified file
170
+ if source && !%i(present installed).include?(should)
171
+ is = self.query
172
+ raise Puppet::Error, _("Could not find package %{name}") % { name: self.name } unless is
173
+
174
+ version = is[:ensure]
175
+
176
+ raise Puppet::Error, _("Failed to update to version %{should}, got version %{version} instead") % { should: should, version: version } unless
177
+ insync?(version)
178
+ end
179
+
158
180
  end
159
181
 
160
182
  # What's the latest package version available?
@@ -231,4 +253,10 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
231
253
  end
232
254
  should_range.include?(is_version)
233
255
  end
256
+
257
+ private
258
+
259
+ def source
260
+ @source ||= @resource[:source]
261
+ end
234
262
  end
@@ -26,4 +26,10 @@ Puppet::Type.type(:package).provide :aptitude, :parent => :apt, :source => :dpkg
26
26
  def purge
27
27
  aptitude '-y', 'purge', @resource[:name]
28
28
  end
29
+
30
+ private
31
+
32
+ def source
33
+ nil
34
+ end
29
35
  end
@@ -17,6 +17,8 @@ Puppet::Type.type(:service).provide :debian, :parent => :init do
17
17
  commands :invoke_rc => "/usr/sbin/invoke-rc.d"
18
18
  commands :service => "/usr/sbin/service"
19
19
 
20
+ confine :false => Puppet::FileSystem.exist?('/proc/1/comm') && Puppet::FileSystem.read('/proc/1/comm').include?('systemd')
21
+
20
22
  defaultfor :operatingsystem => :cumuluslinux, :operatingsystemmajrelease => ['1','2']
21
23
  defaultfor :operatingsystem => :debian, :operatingsystemmajrelease => ['5','6','7']
22
24
  defaultfor :operatingsystem => :devuan
@@ -59,23 +59,37 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
59
59
  get(:uid)
60
60
  end
61
61
 
62
+ def gid
63
+ return localgid if @resource.forcelocal?
64
+ get(:gid)
65
+ end
66
+
62
67
  def comment
63
68
  return localcomment if @resource.forcelocal?
64
69
  get(:comment)
65
70
  end
66
71
 
72
+ def groups
73
+ return localgroups if @resource.forcelocal?
74
+ super
75
+ end
76
+
67
77
  def finduser(key, value)
68
- passwd_file = "/etc/passwd"
78
+ passwd_file = '/etc/passwd'
69
79
  passwd_keys = [:account, :password, :uid, :gid, :gecos, :directory, :shell]
70
- index = passwd_keys.index(key)
71
- @passwd_content ||= File.read(passwd_file)
72
- @passwd_content.each_line do |line|
73
- user = line.split(":")
74
- if user[index] == value
75
- return Hash[passwd_keys.zip(user)]
80
+
81
+ unless @users
82
+ unless Puppet::FileSystem.exist?(passwd_file)
83
+ raise Puppet::Error.new("Forcelocal set for user resource '#{resource[:name]}', but #{passwd_file} does not exist")
84
+ end
85
+
86
+ @users = []
87
+ Puppet::FileSystem.each_line(passwd_file) do |line|
88
+ user = line.chomp.split(':')
89
+ @users << Hash[passwd_keys.zip(user)]
76
90
  end
77
91
  end
78
- false
92
+ @users.find { |param| param[key] == value } || false
79
93
  end
80
94
 
81
95
  def local_username
@@ -88,16 +102,49 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
88
102
  false
89
103
  end
90
104
 
105
+ def localgid
106
+ user = finduser(:account, resource[:name])
107
+ return user[:gid] if user
108
+ false
109
+ end
110
+
91
111
  def localcomment
92
112
  user = finduser(:account, resource[:name])
93
113
  user[:gecos]
94
114
  end
95
115
 
116
+ def localgroups
117
+ @groups_of ||= {}
118
+ group_file = '/etc/group'
119
+ user = resource[:name]
120
+
121
+ return @groups_of[user] if @groups_of[user]
122
+
123
+ @groups_of[user] = []
124
+
125
+ unless Puppet::FileSystem.exist?(group_file)
126
+ raise Puppet::Error.new("Forcelocal set for user resource '#{user}', but #{group_file} does not exist")
127
+ end
128
+
129
+ Puppet::FileSystem.each_line(group_file) do |line|
130
+ data = line.chomp.split(':')
131
+ if data.last.split(',').include?(user)
132
+ @groups_of[user] << data.first
133
+ end
134
+ end
135
+
136
+ @groups_of[user]
137
+ end
138
+
96
139
  def shell=(value)
97
140
  check_valid_shell
98
141
  set(:shell, value)
99
142
  end
100
143
 
144
+ def groups=(value)
145
+ set(:groups, value)
146
+ end
147
+
101
148
  verify :gid, "GID must be an integer" do |value|
102
149
  value.is_a? Integer
103
150
  end
@@ -422,10 +422,10 @@ module Puppet
422
422
  end
423
423
 
424
424
  newparam(:source) do
425
- desc "Where to find the package file. This is only used by providers that don't
425
+ desc "Where to find the package file. This is mostly used by providers that don't
426
426
  automatically download packages from a central repository. (For example:
427
- the `yum` and `apt` providers ignore this attribute, but the `rpm` and
428
- `dpkg` providers require it.)
427
+ the `yum` provider ignores this attribute, `apt` provider uses it if present
428
+ and the `rpm` and `dpkg` providers require it.)
429
429
 
430
430
  Different providers accept different values for `source`. Most providers
431
431
  accept paths to local files stored on the target system. Some providers
@@ -6,7 +6,7 @@
6
6
  # Raketasks and such to set the version based on the output of `git describe`
7
7
 
8
8
  module Puppet
9
- PUPPETVERSION = '7.3.0'
9
+ PUPPETVERSION = '7.4.0'
10
10
 
11
11
  ##
12
12
  # version is a public API method intended to always provide a fast and
data/locales/puppet.pot CHANGED
@@ -6,11 +6,11 @@
6
6
  #, fuzzy
7
7
  msgid ""
8
8
  msgstr ""
9
- "Project-Id-Version: Puppet automation framework 7.1.0-89-g309d69a162\n"
9
+ "Project-Id-Version: Puppet automation framework 7.3.0-6-g7c55ccd544\n"
10
10
  "\n"
11
11
  "Report-Msgid-Bugs-To: https://tickets.puppetlabs.com\n"
12
- "POT-Creation-Date: 2021-01-13 14:37+0000\n"
13
- "PO-Revision-Date: 2021-01-13 14:37+0000\n"
12
+ "POT-Creation-Date: 2021-01-21 13:07+0000\n"
13
+ "PO-Revision-Date: 2021-01-21 13:07+0000\n"
14
14
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
15
15
  "Language-Team: LANGUAGE <LL@li.org>\n"
16
16
  "Language: \n"
@@ -583,44 +583,44 @@ msgstr ""
583
583
  msgid "Local environment: '%{local_env}' doesn't match server specified environment '%{catalog_env}', restarting agent run with environment '%{catalog_env}'"
584
584
  msgstr ""
585
585
 
586
- #: ../lib/puppet/configurer.rb:424
586
+ #: ../lib/puppet/configurer.rb:434
587
587
  msgid "Failed to apply catalog: %{detail}"
588
588
  msgstr ""
589
589
 
590
- #: ../lib/puppet/configurer.rb:453 ../lib/puppet/http/resolver/server_list.rb:63
590
+ #: ../lib/puppet/configurer.rb:463 ../lib/puppet/http/resolver/server_list.rb:63
591
591
  msgid "Puppet server %{host}:%{port} is unavailable: %{code} %{reason}"
592
592
  msgstr ""
593
593
 
594
594
  #. TRANSLATORS 'server_list' is the name of a setting and should not be translated
595
- #: ../lib/puppet/configurer.rb:457 ../lib/puppet/http/resolver/server_list.rb:66
595
+ #: ../lib/puppet/configurer.rb:467 ../lib/puppet/http/resolver/server_list.rb:66
596
596
  msgid "Unable to connect to server from server_list setting: %{detail}"
597
597
  msgstr ""
598
598
 
599
- #: ../lib/puppet/configurer.rb:468 ../lib/puppet/face/report.rb:47
599
+ #: ../lib/puppet/configurer.rb:478 ../lib/puppet/face/report.rb:47
600
600
  msgid "Could not send report: %{detail}"
601
601
  msgstr ""
602
602
 
603
- #: ../lib/puppet/configurer.rb:477
603
+ #: ../lib/puppet/configurer.rb:487
604
604
  msgid "Could not save last run local report: %{detail}"
605
605
  msgstr ""
606
606
 
607
- #: ../lib/puppet/configurer.rb:496
607
+ #: ../lib/puppet/configurer.rb:506
608
608
  msgid "Uploading facts for %{node} to %{server}"
609
609
  msgstr ""
610
610
 
611
- #: ../lib/puppet/configurer.rb:504
611
+ #: ../lib/puppet/configurer.rb:514
612
612
  msgid "Failed to submit facts: %{detail}"
613
613
  msgstr ""
614
614
 
615
- #: ../lib/puppet/configurer.rb:519
615
+ #: ../lib/puppet/configurer.rb:529
616
616
  msgid "Could not run command from %{setting}: %{detail}"
617
617
  msgstr ""
618
618
 
619
- #: ../lib/puppet/configurer.rb:537
619
+ #: ../lib/puppet/configurer.rb:547
620
620
  msgid "Could not retrieve catalog from cache: %{detail}"
621
621
  msgstr ""
622
622
 
623
- #: ../lib/puppet/configurer.rb:558
623
+ #: ../lib/puppet/configurer.rb:568
624
624
  msgid "Could not retrieve catalog from remote server: %{detail}"
625
625
  msgstr ""
626
626
 
@@ -1063,6 +1063,10 @@ msgstr ""
1063
1063
  msgid "Show only the value when the action is called with a single query"
1064
1064
  msgstr ""
1065
1065
 
1066
+ #: ../lib/puppet/face/facts.rb:136
1067
+ msgid "Show how much time it took to resolve each fact."
1068
+ msgstr ""
1069
+
1066
1070
  #: ../lib/puppet/face/generate.rb:9
1067
1071
  msgid "Generates Puppet code from Ruby definitions."
1068
1072
  msgstr ""
@@ -1609,23 +1613,23 @@ msgstr ""
1609
1613
  msgid "Fileserver configuration file does not use '=' as a separator"
1610
1614
  msgstr ""
1611
1615
 
1612
- #: ../lib/puppet/file_serving/configuration/parser.rb:40 ../lib/puppet/util/network_device/config.rb:101
1616
+ #: ../lib/puppet/file_serving/configuration/parser.rb:43 ../lib/puppet/util/network_device/config.rb:101
1613
1617
  msgid "Invalid argument '%{var}' at %{error_location}"
1614
1618
  msgstr ""
1615
1619
 
1616
- #: ../lib/puppet/file_serving/configuration/parser.rb:45
1620
+ #: ../lib/puppet/file_serving/configuration/parser.rb:48
1617
1621
  msgid "Invalid entry at %{error_location}: '%{file_text}'"
1618
1622
  msgstr ""
1619
1623
 
1620
- #: ../lib/puppet/file_serving/configuration/parser.rb:70
1624
+ #: ../lib/puppet/file_serving/configuration/parser.rb:73
1621
1625
  msgid "%{mount} is already mounted at %{name} at %{error_location}"
1622
1626
  msgstr ""
1623
1627
 
1624
- #: ../lib/puppet/file_serving/configuration/parser.rb:95
1628
+ #: ../lib/puppet/file_serving/configuration/parser.rb:98
1625
1629
  msgid "Removing mount \"%{mount}\": %{detail}"
1626
1630
  msgstr ""
1627
1631
 
1628
- #: ../lib/puppet/file_serving/configuration/parser.rb:99
1632
+ #: ../lib/puppet/file_serving/configuration/parser.rb:102
1629
1633
  msgid "The '%{mount}' module can not have a path. Ignoring attempt to set it"
1630
1634
  msgstr ""
1631
1635
 
@@ -7104,24 +7108,24 @@ msgstr ""
7104
7108
  msgid "Setting %{name} is deprecated in puppet.conf."
7105
7109
  msgstr ""
7106
7110
 
7107
- #: ../lib/puppet/settings.rb:1447
7111
+ #: ../lib/puppet/settings.rb:1457
7108
7112
  msgid "Error converting value for param '%{name}': %{detail}"
7109
7113
  msgstr ""
7110
7114
 
7111
- #: ../lib/puppet/settings.rb:1471
7115
+ #: ../lib/puppet/settings.rb:1481
7112
7116
  msgid "Could not find value for %{expression}"
7113
7117
  msgstr ""
7114
7118
 
7115
7119
  #. TRANSLATORS '$environment' is a Puppet specific variable and should not be translated
7116
- #: ../lib/puppet/settings.rb:1481
7120
+ #: ../lib/puppet/settings.rb:1491
7117
7121
  msgid "You cannot interpolate $environment within '%{setting_name}' when using directory environments."
7118
7122
  msgstr ""
7119
7123
 
7120
- #: ../lib/puppet/settings.rb:1482
7124
+ #: ../lib/puppet/settings.rb:1492
7121
7125
  msgid "Its value will remain %{value}."
7122
7126
  msgstr ""
7123
7127
 
7124
- #: ../lib/puppet/settings.rb:1513
7128
+ #: ../lib/puppet/settings.rb:1523
7125
7129
  msgid "Attempt to assign a value to unknown setting %{name}"
7126
7130
  msgstr ""
7127
7131
 
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPETCONF" "5" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPETCONF" "5" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  \fBThis page is autogenerated; any changes will get overwritten\fR
6
6
  .
7
7
  .SH "Configuration settings"
@@ -899,7 +899,7 @@ The time to wait for data to be read from an HTTP connection\. If nothing is rea
899
899
  The HTTP User\-Agent string to send when making network requests\.
900
900
  .
901
901
  .IP "\(bu" 4
902
- \fIDefault\fR: Puppet/7\.3\.0 Ruby/2\.5\.1\-p57 (x86_64\-linux)
902
+ \fIDefault\fR: Puppet/7\.4\.0 Ruby/2\.5\.1\-p57 (x86_64\-linux)
903
903
  .
904
904
  .IP "" 0
905
905
  .
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-AGENT" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-AGENT" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-agent\fR \- The puppet agent daemon
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-APPLY" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-APPLY" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-apply\fR \- Apply Puppet manifests locally
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-CATALOG" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-CATALOG" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-catalog\fR \- Compile, save, view, and convert catalogs\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-CONFIG" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-CONFIG" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-config\fR \- Interact with Puppet\'s settings\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-DESCRIBE" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-DESCRIBE" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-describe\fR \- Display help about resource types
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-DEVICE" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-DEVICE" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-device\fR \- Manage remote network devices
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-DOC" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-DOC" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-doc\fR \- Generate Puppet references
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-EPP" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-EPP" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-epp\fR \- Interact directly with the EPP template parser/renderer\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-FACTS" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-FACTS" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-facts\fR \- Retrieve and store facts\.
@@ -105,7 +105,7 @@ API only: create or overwrite an object\. As the Faces framework does not curren
105
105
  \fBSYNOPSIS\fR
106
106
  .
107
107
  .IP
108
- puppet facts [\-\-terminus _TERMINUS] [\-\-extra HASH] [\-\-config\-file \fIpath\fR] [\-\-custom\-dir \fIpath\fR] [\-\-external\-dir \fIpath\fR] [\-\-no\-block] [\-\-no\-cache] [\-\-show\-legacy] [\-\-value\-only] [\fIfacts\fR]
108
+ puppet facts [\-\-terminus _TERMINUS] [\-\-extra HASH] [\-\-config\-file \fIpath\fR] [\-\-custom\-dir \fIpath\fR] [\-\-external\-dir \fIpath\fR] [\-\-no\-block] [\-\-no\-cache] [\-\-show\-legacy] [\-\-value\-only] [\-\-timing] [\fIfacts\fR]
109
109
  .
110
110
  .IP
111
111
  \fBDESCRIPTION\fR
@@ -132,6 +132,9 @@ Reads facts from the local system using \fBfacter\fR terminus\. A query can be p
132
132
  \fI\-\-show\-legacy\fR \- Show legacy facts when querying all facts\.
133
133
  .
134
134
  .IP
135
+ \fI\-\-timing\fR \- Show how much time it took to resolve each fact\.
136
+ .
137
+ .IP
135
138
  \fI\-\-value\-only\fR \- Show only the value when the action is called with a single query
136
139
  .
137
140
  .IP
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-FILEBUCKET" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-FILEBUCKET" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-filebucket\fR \- Store and retrieve files in a filebucket
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-GENERATE" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-GENERATE" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-generate\fR \- Generates Puppet code from Ruby definitions\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-HELP" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-HELP" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-help\fR \- Display Puppet help\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-LOOKUP" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-LOOKUP" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-lookup\fR \- Interactive Hiera lookup
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-MODULE" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-MODULE" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-module\fR \- Creates, installs and searches for modules on the Puppet Forge\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-NODE" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-NODE" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-node\fR \- View and manage node definitions\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-PARSER" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-PARSER" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-parser\fR \- Interact directly with the parser\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-PLUGIN" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-PLUGIN" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-plugin\fR \- Interact with the Puppet plugin system\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-REPORT" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-REPORT" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-report\fR \- Create, display, and submit reports\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-RESOURCE" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-RESOURCE" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-resource\fR \- The resource abstraction layer shell
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-SCRIPT" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-SCRIPT" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-script\fR \- Run a puppet manifests as a script without compiling a catalog
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-SSL" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-SSL" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-ssl\fR \- Manage SSL keys and certificates for puppet SSL clients
data/man/man8/puppet.8 CHANGED
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET" "8" "January 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET" "8" "February 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\fR
@@ -25,4 +25,4 @@ Specialized:
25
25
  catalog Compile, save, view, and convert catalogs\. describe Display help about resource types device Manage remote network devices doc Generate Puppet references epp Interact directly with the EPP template parser/renderer\. facts Retrieve and store facts\. filebucket Store and retrieve files in a filebucket generate Generates Puppet code from Ruby definitions\. node View and manage node definitions\. parser Interact directly with the parser\. plugin Interact with the Puppet plugin system\. script Run a puppet manifests as a script without compiling a catalog ssl Manage SSL keys and certificates for puppet SSL clients
26
26
  .
27
27
  .P
28
- See \'puppet help \fIsubcommand\fR \fIaction\fR\' for help on a specific subcommand action\. See \'puppet help \fIsubcommand\fR\' for help on a specific subcommand\. Puppet v7\.3\.0
28
+ See \'puppet help \fIsubcommand\fR \fIaction\fR\' for help on a specific subcommand action\. See \'puppet help \fIsubcommand\fR\' for help on a specific subcommand\. Puppet v7\.4\.0
@@ -613,4 +613,37 @@ describe "puppet agent", unless: Puppet::Util::Platform.jruby? do
613
613
  expect(File).to_not be_exist(cached_catalog)
614
614
  end
615
615
  end
616
+
617
+ context "reporting" do
618
+ it "stores a finalized report" do
619
+ catalog_handler = -> (req, res) {
620
+ catalog = compile_to_catalog(<<-MANIFEST, node)
621
+ notify { 'foo':
622
+ require => Notify['bar']
623
+ }
624
+
625
+ notify { 'bar':
626
+ require => Notify['foo']
627
+ }
628
+ MANIFEST
629
+
630
+ res.body = formatter.render(catalog)
631
+ res['Content-Type'] = formatter.mime
632
+ }
633
+
634
+ server.start_server(mounts: {catalog: catalog_handler}) do |port|
635
+ Puppet[:serverport] = port
636
+ expect {
637
+ agent.command_line.args << '--test'
638
+ agent.run
639
+ }.to exit_with(1)
640
+ .and output(%r{Applying configuration}).to_stdout
641
+ .and output(%r{Found 1 dependency cycle}).to_stderr
642
+
643
+ report = Puppet::Transaction::Report.convert_from(:yaml, File.read(Puppet[:lastrunreport]))
644
+ expect(report.status).to eq("failed")
645
+ expect(report.metrics).to_not be_empty
646
+ end
647
+ end
648
+ end
616
649
  end
@@ -52,7 +52,12 @@ describe Puppet::Application::Facts do
52
52
  end
53
53
 
54
54
  context 'when show action is called' do
55
- let(:expected) { "{\n \"filesystems\": \"apfs,autofs,devfs\",\n \"macaddress\": \"64:52:11:22:03:25\"\n}\n" }
55
+ let(:expected) { <<~END }
56
+ {
57
+ "filesystems": "apfs,autofs,devfs",
58
+ "macaddress": "64:52:11:22:03:25"
59
+ }
60
+ END
56
61
 
57
62
  before :each do
58
63
  Puppet::Node::Facts.indirection.terminus_class = :facter
@@ -64,12 +69,58 @@ describe Puppet::Application::Facts do
64
69
  expect {
65
70
  app.run
66
71
  }.to exit_with(0)
67
- .and output(expected).to_stdout
72
+ .and output(expected).to_stdout
73
+ end
74
+
75
+ it 'displays a single fact value' do
76
+ app.command_line.args << 'filesystems' << '--value-only'
77
+ expect {
78
+ app.run
79
+ }.to exit_with(0)
80
+ .and output("apfs,autofs,devfs\n").to_stdout
81
+ end
82
+
83
+ it "warns and ignores value-only when multiple fact names are specified" do
84
+ app.command_line.args << 'filesystems' << 'macaddress' << '--value-only'
85
+ expect {
86
+ app.run
87
+ }.to exit_with(0)
88
+ .and output(expected).to_stdout
89
+ .and output(/it can only be used when querying for a single fact/).to_stderr
90
+ end
91
+
92
+ {
93
+ "type_hash" => [{'a' => 2}, "{\n \"a\": 2\n}"],
94
+ "type_array" => [[], "[\n\n]"],
95
+ "type_string" => ["str", "str"],
96
+ "type_int" => [1, "1"],
97
+ "type_float" => [1.0, "1.0"],
98
+ "type_true" => [true, "true"],
99
+ "type_false" => [false, "false"],
100
+ "type_nil" => [nil, ""],
101
+ "type_sym" => [:sym, "sym"]
102
+ }.each_pair do |name, values|
103
+ it "renders '#{name}' as '#{values.last}'" do
104
+ fact_value = values.first
105
+ fact_output = values.last
106
+
107
+ allow(Facter).to receive(:resolve).and_return({name => fact_value})
108
+
109
+ app.command_line.args << name << '--value-only'
110
+ expect {
111
+ app.run
112
+ }.to exit_with(0)
113
+ .and output("#{fact_output}\n").to_stdout
114
+ end
68
115
  end
69
116
  end
70
117
 
71
118
  context 'when default action is called' do
72
- let(:expected) { "---\nfilesystems: apfs,autofs,devfs\nmacaddress: 64:52:11:22:03:25\n" }
119
+ let(:expected) { <<~END }
120
+ ---
121
+ filesystems: apfs,autofs,devfs
122
+ macaddress: 64:52:11:22:03:25
123
+ END
73
124
 
74
125
  before :each do
75
126
  Puppet::Node::Facts.indirection.terminus_class = :facter
@@ -81,7 +132,7 @@ describe Puppet::Application::Facts do
81
132
  expect {
82
133
  app.run
83
134
  }.to exit_with(0)
84
- .and output(expected).to_stdout
135
+ .and output(expected).to_stdout
85
136
  expect(app.action.name).to eq(:show)
86
137
  end
87
138
  end
@@ -182,6 +182,15 @@ describe Puppet::Node::Facts::Facter do
182
182
  end
183
183
  end
184
184
 
185
+ context 'when --timing flag is present' do
186
+ let(:options) { { resolve_options: true, user_query: ["os", "timezone"], timing: true } }
187
+
188
+ it 'calls Facter.resolve with --timing' do
189
+ expect(Facter).to receive(:resolve).with("os timezone --timing")
190
+ @facter.find(@request)
191
+ end
192
+ end
193
+
185
194
  describe 'when Facter version is lower than 4.0.40' do
186
195
  before :each do
187
196
  allow(Facter).to receive(:respond_to?).and_return(false)
@@ -198,7 +198,10 @@ describe Puppet::Type.type(:group).provider(:groupadd) do
198
198
  end
199
199
 
200
200
  describe "#findgroup" do
201
- before { allow(File).to receive(:read).with('/etc/group').and_return(content) }
201
+ before do
202
+ allow(Puppet::FileSystem).to receive(:exist?).with('/etc/group').and_return(true)
203
+ allow(Puppet::FileSystem).to receive(:each_line).with('/etc/group').and_yield(content)
204
+ end
202
205
 
203
206
  let(:content) { "sample_group_name:sample_password:sample_gid:sample_user_list" }
204
207
  let(:output) do
@@ -221,7 +224,7 @@ describe Puppet::Type.type(:group).provider(:groupadd) do
221
224
  end
222
225
 
223
226
  it "reads the group file only once per resource" do
224
- expect(File).to receive(:read).with('/etc/group').once
227
+ expect(Puppet::FileSystem).to receive(:each_line).with('/etc/group').once
225
228
  5.times { provider.send(:findgroup, :group_name, 'sample_group_name') }
226
229
  end
227
230
  end
@@ -115,24 +115,12 @@ Version table:
115
115
  allow(provider).to receive(:dpkgquery).and_return("name: #{resource.name}" )
116
116
  end
117
117
 
118
- context "when package is manual marked" do
119
- before do
120
- allow(described_class).to receive(:aptmark).with('showmanual').and_return("#{resource.name}\n")
121
- end
122
-
123
- it 'sets mark to manual' do
124
- result = provider.query
125
- expect(result[:mark]).to eql(:manual)
126
- end
127
- end
128
-
129
- context 'when package is not manual marked ' do
130
- before do
131
- allow(described_class).to receive(:aptmark).with('showmanual').and_return('')
132
- end
133
118
 
119
+ context 'when package is not installed on the system' do
134
120
  it 'does not set mark to manual' do
135
121
  result = provider.query
122
+
123
+ expect(described_class).not_to receive(:aptmark)
136
124
  expect(result[:mark]).to be_nil
137
125
  end
138
126
  end
@@ -289,5 +277,26 @@ Version table:
289
277
 
290
278
  provider.install
291
279
  end
280
+
281
+ it "should install using the source attribute if present" do
282
+ resource[:ensure] = :installed
283
+ resource[:source] = '/my/local/package/file'
284
+
285
+ expect(provider).to receive(:aptget).with(any_args, :install, resource[:source])
286
+ expect(provider).to receive(:properties).and_return({:mark => :none})
287
+
288
+ provider.install
289
+ end
290
+
291
+ it "should install specific version using the source attribute if present" do
292
+ resource[:ensure] = '1.2.3'
293
+ resource[:source] = '/my/local/package/file'
294
+
295
+ expect(provider).to receive(:aptget).with(any_args, :install, resource[:source])
296
+ expect(provider).to receive(:properties).and_return({:mark => :none})
297
+ expect(provider).to receive(:query).and_return({:ensure => '1.2.3'})
298
+
299
+ provider.install
300
+ end
292
301
  end
293
302
  end
@@ -13,7 +13,7 @@ describe Puppet::Type.type(:package).provider(:aptitude) do
13
13
 
14
14
  before do
15
15
  allow(Puppet::Util).to receive(:which).with('/usr/bin/dpkg-query').and_return(dpkgquery_path)
16
- allow(described_class).to receive(:aptmark).with('showmanual').and_return("")
16
+ allow(described_class).to receive(:aptmark).with('showmanual', 'faff').and_return("")
17
17
  end
18
18
 
19
19
  { :absent => "deinstall ok config-files faff 1.2.3-1\n",
@@ -152,6 +152,7 @@ describe Puppet::Type.type(:user).provider(:useradd) do
152
152
 
153
153
  it "should not use -G for luseradd and should call usermod with -G after luseradd when groups property is set" do
154
154
  resource[:groups] = ['group1', 'group2']
155
+ allow(provider).to receive(:localgroups)
155
156
  expect(provider).to receive(:execute).with(include('/usr/sbin/luseradd').and(excluding('-G')), hash_including(custom_environment: hash_including('LIBUSER_CONF')))
156
157
  expect(provider).to receive(:execute).with(include('/usr/sbin/usermod').and(include('-G')), hash_including(custom_environment: hash_including('LIBUSER_CONF')))
157
158
  provider.create
@@ -337,7 +338,8 @@ describe Puppet::Type.type(:user).provider(:useradd) do
337
338
 
338
339
  it "should return the local comment string when forcelocal is true" do
339
340
  resource[:forcelocal] = true
340
- allow(File).to receive(:read).with('/etc/passwd').and_return(content)
341
+ allow(Puppet::FileSystem).to receive(:exist?).with('/etc/passwd').and_return(true)
342
+ allow(Puppet::FileSystem).to receive(:each_line).with('/etc/passwd').and_yield(content)
341
343
  expect(provider.comment).to eq('local comment')
342
344
  end
343
345
 
@@ -349,8 +351,58 @@ describe Puppet::Type.type(:user).provider(:useradd) do
349
351
  end
350
352
  end
351
353
 
354
+ describe "#gid" do
355
+ before { described_class.has_feature :manages_local_users_and_groups }
356
+
357
+ let(:content) { "myuser:x:x:999:x:x:x" }
358
+
359
+ it "should return the local GID when forcelocal is true" do
360
+ resource[:forcelocal] = true
361
+ allow(Puppet::FileSystem).to receive(:exist?).with('/etc/passwd').and_return(true)
362
+ allow(Puppet::FileSystem).to receive(:each_line).with('/etc/passwd').and_yield(content)
363
+ expect(provider.gid).to eq('999')
364
+ end
365
+
366
+ it "should fall back to nameservice GID when forcelocal is false" do
367
+ resource[:forcelocal] = false
368
+ allow(provider).to receive(:get).with(:gid).and_return('1234')
369
+ expect(provider).not_to receive(:localgid)
370
+ expect(provider.gid).to eq('1234')
371
+ end
372
+ end
373
+
374
+ describe "#groups" do
375
+ before { described_class.has_feature :manages_local_users_and_groups }
376
+
377
+ let(:content) do
378
+ <<~EOF
379
+ group1:x:0:myuser
380
+ group2:x:999:
381
+ group3:x:998:myuser
382
+ EOF
383
+ end
384
+
385
+ it "should return the local groups string when forcelocal is true" do
386
+ resource[:forcelocal] = true
387
+ group1, group2, group3 = content.split
388
+ allow(Puppet::FileSystem).to receive(:exist?).with('/etc/group').and_return(true)
389
+ allow(Puppet::FileSystem).to receive(:each_line).with('/etc/group').and_yield(group1).and_yield(group2).and_yield(group3)
390
+ expect(provider.groups).to eq(['group1', 'group3'])
391
+ end
392
+
393
+ it "should fall back to nameservice groups when forcelocal is false" do
394
+ resource[:forcelocal] = false
395
+ allow(Puppet::Util::POSIX).to receive(:groups_of).with('myuser').and_return(['remote groups'])
396
+ expect(provider).not_to receive(:localgroups)
397
+ expect(provider.groups).to eq('remote groups')
398
+ end
399
+ end
400
+
352
401
  describe "#finduser" do
353
- before { allow(File).to receive(:read).with('/etc/passwd').and_return(content) }
402
+ before do
403
+ allow(Puppet::FileSystem).to receive(:exist?).with('/etc/passwd').and_return(true)
404
+ allow(Puppet::FileSystem).to receive(:each_line).with('/etc/passwd').and_yield(content)
405
+ end
354
406
 
355
407
  let(:content) { "sample_account:sample_password:sample_uid:sample_gid:sample_gecos:sample_directory:sample_shell" }
356
408
  let(:output) do
@@ -376,7 +428,7 @@ describe Puppet::Type.type(:user).provider(:useradd) do
376
428
  end
377
429
 
378
430
  it "reads the user file only once per resource" do
379
- expect(File).to receive(:read).with('/etc/passwd').once
431
+ expect(Puppet::FileSystem).to receive(:each_line).with('/etc/passwd').once
380
432
  5.times { provider.finduser(:account, 'sample_account') }
381
433
  end
382
434
  end
@@ -320,11 +320,8 @@ describe Puppet::SSL::CertificateRequest do
320
320
  expect(csr.verify(key)).to be_truthy
321
321
  end
322
322
 
323
- # Attempts to use SHA512 and SHA384 for signing certificates don't seem to work
324
- # So commenting it out till it is sorted out
325
- # The problem seems to be with the ability to sign a CSR when using either of
326
- # these hash algorithms
327
- pending "should use SHA512 to sign the csr when SHA256 and SHA1 aren't available" do
323
+ it "should use SHA512 to sign the csr when SHA256 and SHA1 aren't available" do
324
+ key = OpenSSL::PKey::RSA.new(2048)
328
325
  csr = OpenSSL::X509::Request.new
329
326
  expect(OpenSSL::Digest).to receive(:const_defined?).with("SHA256").and_return(false)
330
327
  expect(OpenSSL::Digest).to receive(:const_defined?).with("SHA1").and_return(false)
@@ -334,11 +331,8 @@ describe Puppet::SSL::CertificateRequest do
334
331
  expect(csr.verify(key)).to be_truthy
335
332
  end
336
333
 
337
- # Attempts to use SHA512 and SHA384 for signing certificates don't seem to work
338
- # So commenting it out till it is sorted out
339
- # The problem seems to be with the ability to sign a CSR when using either of
340
- # these hash algorithms
341
- pending "should use SHA384 to sign the csr when SHA256/SHA1/SHA512 aren't available" do
334
+ it "should use SHA384 to sign the csr when SHA256/SHA1/SHA512 aren't available" do
335
+ key = OpenSSL::PKey::RSA.new(2048)
342
336
  csr = OpenSSL::X509::Request.new
343
337
  expect(OpenSSL::Digest).to receive(:const_defined?).with("SHA256").and_return(false)
344
338
  expect(OpenSSL::Digest).to receive(:const_defined?).with("SHA1").and_return(false)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.3.0
4
+ version: 7.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet Labs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-19 00:00:00.000000000 Z
11
+ date: 2021-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: facter