puppet 4.4.0 → 4.4.1

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/conf/puppet.conf +1 -1
  3. data/ext/redhat/puppet.spec.erb +0 -9
  4. data/ext/upload_facts.rb +1 -1
  5. data/lib/puppet/application/agent.rb +1 -1
  6. data/lib/puppet/application/apply.rb +1 -1
  7. data/lib/puppet/application/cert.rb +1 -1
  8. data/lib/puppet/application/filebucket.rb +1 -1
  9. data/lib/puppet/application/inspect.rb +2 -2
  10. data/lib/puppet/application/lookup.rb +7 -7
  11. data/lib/puppet/application/master.rb +1 -1
  12. data/lib/puppet/application/resource.rb +1 -1
  13. data/lib/puppet/data_providers/hiera_interpolate.rb +46 -3
  14. data/lib/puppet/defaults.rb +2 -2
  15. data/lib/puppet/face/config.rb +1 -1
  16. data/lib/puppet/face/help/man.erb +1 -1
  17. data/lib/puppet/functions/hiera_include.rb +2 -2
  18. data/lib/puppet/functions/inline_epp.rb +1 -1
  19. data/lib/puppet/parser/functions/hiera_include.rb +2 -2
  20. data/lib/puppet/parser/functions/inline_epp.rb +1 -1
  21. data/lib/puppet/pops/types/type_mismatch_describer.rb +2 -4
  22. data/lib/puppet/pops/types/types.rb +12 -12
  23. data/lib/puppet/provider/package/pip3.rb +2 -0
  24. data/lib/puppet/reference/providers.rb +1 -1
  25. data/lib/puppet/resource/catalog.rb +3 -1
  26. data/lib/puppet/transaction.rb +0 -24
  27. data/lib/puppet/type.rb +4 -4
  28. data/lib/puppet/type/file.rb +3 -5
  29. data/lib/puppet/type/file/content.rb +2 -2
  30. data/lib/puppet/type/filebucket.rb +1 -1
  31. data/lib/puppet/type/schedule.rb +1 -1
  32. data/lib/puppet/type/stage.rb +1 -1
  33. data/lib/puppet/version.rb +1 -1
  34. data/spec/integration/data_binding_spec.rb +0 -34
  35. data/spec/unit/application/inspect_spec.rb +19 -8
  36. data/spec/unit/data_providers/hiera_interpolation_spec.rb +260 -12
  37. data/spec/unit/provider/package/pip3_spec.rb +8 -0
  38. data/spec/unit/provider/package/pip_spec.rb +8 -0
  39. data/spec/unit/provider/service/systemd_spec.rb +1 -1
  40. data/spec/unit/resource/catalog_spec.rb +27 -0
  41. metadata +2 -3
  42. data/ext/puppet-nm-dispatcher +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 09f4069eb54dee692c19820f97cdd1785bab0dbb
4
- data.tar.gz: 75ceac304aa7d93d05d7aef8badcfca74960d83a
3
+ metadata.gz: 1c7bad036d27e2716b93a5cc771933aab98fce61
4
+ data.tar.gz: 2ff2acdc598315acfcacd66e3eb423b3cb359ada
5
5
  SHA512:
6
- metadata.gz: 27d55c8abc6d2f688d7672a893ff41f5a6cb46f5c77fec5f5de493b81a47934377c890c2791c6918f1563672ad2d67bafed09078c021c2393688b1649b198266
7
- data.tar.gz: a264055b603228a1b909234055387b723d0cc923c18aa7ab74c9ff1386a9ac0b5670bcbefd278b0f03ce05ba0ebf6560499d895f1dcaf70b3bb992be022dde06
6
+ metadata.gz: 2aa426cd787f2b53cb0adbfd19be5dc5d1047735048867a5068a56f8aff272a66e882162a3d0c4a90b4b202bc426255295e6b0036a7cfa8fe5d4b14f82d46940
7
+ data.tar.gz: 45e11a87313065ee36c651c41fdb0c84ab3a838fbcf5430d5e26db23e440a91ca86f75f412e99cb6c10ef4eb401f907f5cc46a9510280f750b47af6e04d2bbb0
@@ -3,4 +3,4 @@
3
3
  # - https://docs.puppetlabs.com/puppet/latest/reference/config_important_settings.html
4
4
  # - https://docs.puppetlabs.com/puppet/latest/reference/config_about_settings.html
5
5
  # - https://docs.puppetlabs.com/puppet/latest/reference/config_file_main.html
6
- # - https://docs.puppetlabs.com/references/latest/configuration.html
6
+ # - https://docs.puppetlabs.com/puppet/latest/reference/configuration.html
@@ -181,12 +181,6 @@ echo "D /var/run/%{name} 0755 %{name} %{name} -" > \
181
181
  # Create puppet modules directory for puppet module tool
182
182
  mkdir -p %{buildroot}%{_sysconfdir}/%{name}/modules
183
183
 
184
- # Install a NetworkManager dispatcher script to pickup changes to
185
- # # /etc/resolv.conf and such (https://bugzilla.redhat.com/532085).
186
- mkdir -p %{buildroot}%{_sysconfdir}/NetworkManager/dispatcher.d
187
- cp -pr ext/puppet-nm-dispatcher \
188
- %{buildroot}%{_sysconfdir}/NetworkManager/dispatcher.d/98-%{name}
189
-
190
184
  # Masterhttp.log is created on server start and should be distributed
191
185
  # with correct permissions
192
186
  touch %{buildroot}%{_localstatedir}/log/puppet/masterhttp.log
@@ -197,9 +191,6 @@ touch %{buildroot}%{_localstatedir}/log/puppet/masterhttp.log
197
191
  %{_bindir}/puppet
198
192
  %{_bindir}/extlookup2hiera
199
193
  %{puppet_libdir}/*
200
- %dir %{_sysconfdir}/NetworkManager
201
- %dir %{_sysconfdir}/NetworkManager/dispatcher.d
202
- %{_sysconfdir}/NetworkManager/dispatcher.d/98-puppet
203
194
  %if 0%{?_with_systemd}
204
195
  %{_unitdir}/puppet.service
205
196
  %{_unitdir}/puppetagent.service
@@ -58,7 +58,7 @@ is also a valid long argument. For example, 'server' is a valid configuration
58
58
  parameter, so you can specify '--server <servername>' as an argument.
59
59
 
60
60
  See the configuration file documentation at
61
- https://docs.puppetlabs.com/references/stable/configuration.html for
61
+ https://docs.puppetlabs.com/puppet/latest/reference/configuration.html for
62
62
  the full list of acceptable parameters. A commented list of all
63
63
  configuration options can also be generated by running puppet agent with
64
64
  '--genconfig'.
@@ -155,7 +155,7 @@ specify '--server <servername>' as an argument. Boolean settings translate into
155
155
  '--setting' and '--no-setting' pairs.
156
156
 
157
157
  See the configuration file documentation at
158
- https://docs.puppetlabs.com/references/stable/configuration.html for the
158
+ https://docs.puppetlabs.com/puppet/latest/reference/configuration.html for the
159
159
  full list of acceptable settings. A commented list of all settings can also be
160
160
  generated by running puppet agent with '--genconfig'.
161
161
 
@@ -74,7 +74,7 @@ valid setting, so you can specify '--tags <class>,<tag>'
74
74
  as an argument.
75
75
 
76
76
  See the configuration file documentation at
77
- https://docs.puppetlabs.com/references/stable/configuration.html for the
77
+ https://docs.puppetlabs.com/puppet/latest/reference/configuration.html for the
78
78
  full list of acceptable parameters. A commented list of all
79
79
  configuration options can also be generated by running puppet with
80
80
  '--genconfig'.
@@ -164,7 +164,7 @@ setting, so you can specify '--ssldir <directory>' as an
164
164
  argument.
165
165
 
166
166
  See the configuration file documentation at
167
- https://docs.puppetlabs.com/references/stable/configuration.html for the
167
+ https://docs.puppetlabs.com/puppet/latest/reference/configuration.html for the
168
168
  full list of acceptable parameters. A commented list of all
169
169
  configuration options can also be generated by running puppet cert with
170
170
  '--genconfig'.
@@ -73,7 +73,7 @@ setting, so you can specify '--ssldir <directory>' as an
73
73
  argument.
74
74
 
75
75
  See the configuration file documentation at
76
- https://docs.puppetlabs.com/references/stable/configuration.html for the
76
+ https://docs.puppetlabs.com/puppet/latest/reference/configuration.html for the
77
77
  full list of acceptable parameters. A commented list of all
78
78
  configuration options can also be generated by running puppet with
79
79
  '--genconfig'.
@@ -48,7 +48,7 @@ OPTIONS
48
48
  Any configuration setting which is valid in the configuration file is
49
49
  also a valid long argument, e.g. '--server=master.domain.com'. See the
50
50
  configuration file documentation at
51
- https://docs.puppetlabs.com/references/latest/configuration.html for
51
+ https://docs.puppetlabs.com/puppet/latest/reference/configuration.html for
52
52
  the full list of acceptable settings.
53
53
 
54
54
  * --archive_files:
@@ -91,7 +91,7 @@ Copyright (c) 2011 Puppet Labs, LLC Licensed under the Apache 2.0 License
91
91
  set_log_level
92
92
 
93
93
  Puppet::Transaction::Report.indirection.terminus_class = :rest
94
- Puppet::Resource::Catalog.indirection.terminus_class = :yaml
94
+ Puppet::Resource::Catalog.indirection.terminus_class = Puppet[:catalog_cache_terminus] || :json
95
95
  end
96
96
 
97
97
  def preinit
@@ -35,7 +35,7 @@ class Puppet::Application::Lookup < Puppet::Application
35
35
 
36
36
  option('--sort-merge-arrays')
37
37
 
38
- option('--unpack-arrays') do |arg|
38
+ option('--unpack-arrays DELIMITER') do |arg|
39
39
  options[:unpack_arrays] = arg
40
40
  end
41
41
 
@@ -164,19 +164,19 @@ the puppet lookup function linked to above.
164
164
  removed. 'deep' Performs a deep merge on values of Array and Hash type. There
165
165
  are additional option flags that can be used with 'deep'.
166
166
 
167
- * --knock_out_prefix <PREFIX-STRING>
167
+ * --knock-out-prefix <PREFIX-STRING>
168
168
  Can be used with the 'deep' merge strategy. Specify string value to signify
169
169
  prefix which deletes elements from existing element.
170
170
 
171
- * --sort_merged_arrays
171
+ * --sort-merged-arrays
172
172
  Can be used with the 'deep' merge strategy. When this flag is used all
173
173
  merged arrays will be sorted.
174
174
 
175
- * --unpack_arrays <STRING-VALUE>
175
+ * --unpack-arrays <STRING-VALUE>
176
176
  Can be used with the 'deep' merge strategy. Specify a string value used
177
177
  as a deliminator to join all array values and then split them again.
178
178
 
179
- * --merge_hash_arrays
179
+ * --merge-hash-arrays
180
180
  Can be used with the 'deep' merge strategy. When this flag is used arrays
181
181
  and hashes will be merged.
182
182
 
@@ -272,11 +272,11 @@ Copyright (c) 2015 Puppet Labs, LLC Licensed under the Apache 2.0 License
272
272
  'merge_hash_arrays' => !options[:merge_hash_arrays].nil?}
273
273
 
274
274
  if options[:prefix]
275
- merge_options.merge({'prefix' => options[:prefix]})
275
+ merge_options.merge!({'knockout_prefix' => options[:prefix]})
276
276
  end
277
277
 
278
278
  if options[:unpack_arrays]
279
- merge_options.merge({'unpack_arrays' => options[:unpack_arrays]})
279
+ merge_options.merge!({'unpack_arrays' => options[:unpack_arrays]})
280
280
  end
281
281
 
282
282
  else
@@ -61,7 +61,7 @@ specify '--server <servername>' as an argument. Boolean settings translate into
61
61
  '--setting' and '--no-setting' pairs.
62
62
 
63
63
  See the configuration file documentation at
64
- https://docs.puppetlabs.com/references/stable/configuration.html for the
64
+ https://docs.puppetlabs.com/puppet/latest/reference/configuration.html for the
65
65
  full list of acceptable settings. A commented list of all settings can also be
66
66
  generated by running puppet master with '--genconfig'.
67
67
 
@@ -72,7 +72,7 @@ setting, so you can specify '--ssldir <directory>' as an
72
72
  argument.
73
73
 
74
74
  See the configuration file documentation at
75
- https://docs.puppetlabs.com/references/stable/configuration.html for the
75
+ https://docs.puppetlabs.com/puppet/latest/reference/configuration.html for the
76
76
  full list of acceptable parameters. A commented list of all
77
77
  configuration options can also be generated by running puppet with
78
78
  '--genconfig'.
@@ -19,20 +19,32 @@ module Puppet::DataProviders::HieraInterpolate
19
19
 
20
20
  private
21
21
 
22
+ EMPTY_INTERPOLATIONS = {
23
+ '' => true,
24
+ '::' => true,
25
+ '""' => true,
26
+ "''" => true,
27
+ '"::"' => true,
28
+ "'::'" => true
29
+ }.freeze
30
+
31
+ # Matches a key that is quoted using a matching pair of either single or double quotes.
32
+ QUOTED_KEY = /^(?:"([^"]+)"|'([^']+)')$/
33
+
22
34
  def interpolate_string(subject, lookup_invocation, allow_methods)
23
35
  lookup_invocation.with(:interpolate, subject) do
24
36
  subject.gsub(/%\{([^\}]*)\}/) do |match|
25
37
  expr = $1
26
38
  # Leading and trailing spaces inside an interpolation expression are insignificant
27
39
  expr.strip!
28
- unless expr.empty? || expr == '::'
40
+ unless EMPTY_INTERPOLATIONS[expr]
29
41
  method_key, key = get_method_and_data(expr, allow_methods)
30
42
  is_alias = method_key == 'alias'
31
43
 
32
44
  # Alias is only permitted if the entire string is equal to the interpolate expression
33
45
  raise Puppet::DataBinding::LookupError, "'alias' interpolation is only permitted if the expression is equal to the entire string" if is_alias && subject != match
34
46
 
35
- segments = key.split('.')
47
+ segments = split_key(key) { |problem| Puppet::DataBinding::LookupError.new("#{problem} in string: #{subject}") }
36
48
  value = interpolate_method(method_key).call(segments[0], lookup_invocation)
37
49
  value = qualified_lookup(segments.drop(1), value) if segments.size > 1
38
50
  value = lookup_invocation.check(key) { interpolate(value, lookup_invocation, allow_methods) }
@@ -76,7 +88,7 @@ module Puppet::DataProviders::HieraInterpolate
76
88
  'alias' => global_lookup, # same as 'lookup' but expression must be entire string. The result that is not subject to string substitution
77
89
  'scope' => scope_lookup,
78
90
  'literal' => lambda { |key, _| key }
79
- }
91
+ }.freeze
80
92
  end
81
93
  interpolate_method = @@interpolate_methods[method_key]
82
94
  raise Puppet::DataBinding::LookupError, "Unknown interpolation method '#{method_key}'" unless interpolate_method
@@ -109,4 +121,35 @@ module Puppet::DataProviders::HieraInterpolate
109
121
  end
110
122
  [key, data]
111
123
  end
124
+
125
+ # Split key into segments. A segment may be a quoted string (both single and double quotes can
126
+ # be used) and the segment separator is the '.' character. Whitespace will be trimmed off on
127
+ # both sides of each segment. Whitespace within quotes are not trimmed.
128
+ #
129
+ # If the key cannot be parsed, this method will yield a string describing the problem to a one
130
+ # parameter block. The block must return an exception instance.
131
+ #
132
+ # @param key [String] the string to split
133
+ # @return Array<String> the array of segments
134
+ # @yieldparam problem [String] the problem, i.e. 'Syntax error'
135
+ # @yieldreturn [Exception] the exception to raise
136
+ def split_key(key)
137
+ segments = key.split(/(\s*"[^"]+"\s*|\s*'[^']+'\s*|[^'".]+)/)
138
+ if segments.empty?
139
+ # Only happens if the original key was an empty string
140
+ ''
141
+ elsif segments.shift == ''
142
+ count = segments.size
143
+ raise yield('Syntax error') unless count > 0
144
+
145
+ segments.keep_if { |seg| seg != '.' }
146
+ raise yield('Syntax error') unless segments.size * 2 == count + 1
147
+ segments.map! do |segment|
148
+ segment.strip!
149
+ segment.start_with?('"') || segment.start_with?("'") ? segment[1..-2] : segment
150
+ end
151
+ else
152
+ raise yield('Syntax error')
153
+ end
154
+ end
112
155
  end
@@ -1310,7 +1310,7 @@ EOT
1310
1310
  For control over logging destinations, see the `--logdest` command line
1311
1311
  option in the manual pages for puppet master, puppet agent, and puppet
1312
1312
  apply. You can see man pages by running `puppet <SUBCOMMAND> --help`,
1313
- or read them online at https://docs.puppetlabs.com/references/latest/man/."
1313
+ or read them online at https://docs.puppetlabs.com/puppet/latest/reference/man/."
1314
1314
  },
1315
1315
  :server => {
1316
1316
  :default => "puppet",
@@ -1355,7 +1355,7 @@ EOT
1355
1355
  event _would_ have been sent.
1356
1356
 
1357
1357
  **Important note:**
1358
- [The `noop` metaparameter](https://docs.puppetlabs.com/references/latest/metaparameter.html#noop)
1358
+ [The `noop` metaparameter](https://docs.puppetlabs.com/puppet/latest/reference/metaparameter.html#noop)
1359
1359
  allows you to apply individual resources in noop mode, and will override
1360
1360
  the global value of the `noop` setting. This means a resource with
1361
1361
  `noop => false` _will_ be changed if necessary, even when running puppet
@@ -9,7 +9,7 @@ Puppet::Face.define(:config, '0.0.1') do
9
9
 
10
10
  description "This subcommand can inspect and modify settings from Puppet's
11
11
  'puppet.conf' configuration file. For documentation about individual settings,
12
- see https://docs.puppetlabs.com/references/latest/configuration.html."
12
+ see https://docs.puppetlabs.com/puppet/latest/reference/configuration.html."
13
13
 
14
14
  option "--section SECTION_NAME" do
15
15
  default_to { "main" }
@@ -23,7 +23,7 @@ settings, so you can specify `--server <servername>`, or
23
23
  `--run_mode <runmode>` as an argument.
24
24
 
25
25
  See the configuration file documentation at
26
- <https://docs.puppetlabs.com/references/stable/configuration.html> for the
26
+ <https://docs.puppetlabs.com/puppet/latest/reference/configuration.html> for the
27
27
  full list of acceptable parameters. A commented list of all
28
28
  configuration options can also be generated by running puppet with
29
29
  `--genconfig`.
@@ -1,7 +1,7 @@
1
1
  require 'hiera/puppet_function'
2
2
 
3
3
  # Assigns classes to a node using an
4
- # [array merge lookup](https://docs.puppetlabs.com/hiera/latest/lookup_types.htmlarray-merge)
4
+ # [array merge lookup](https://docs.puppetlabs.com/hiera/latest/lookup_types.html#array-merge)
5
5
  # that retrieves the value for a user-specified key from Hiera's data.
6
6
  #
7
7
  # The `hiera_include` function requires:
@@ -26,7 +26,7 @@ require 'hiera/puppet_function'
26
26
  # searching the rest of the hierarchy.
27
27
  #
28
28
  # The function uses an
29
- # [array merge lookup](https://docs.puppetlabs.com/hiera/latest/lookup_types.htmlarray-merge)
29
+ # [array merge lookup](https://docs.puppetlabs.com/hiera/latest/lookup_types.html#array-merge)
30
30
  # to retrieve the `classes` array, so every node gets every class from the hierarchy.
31
31
  #
32
32
  # @example Using `hiera_include`
@@ -28,7 +28,7 @@
28
28
  # `inline_epp` function fails to pass any required parameter.
29
29
  #
30
30
  # An inline EPP template should be written as a single-quoted string or
31
- # [heredoc](puppet/latest/reference/lang_data_string.html#heredocs).
31
+ # [heredoc](/puppet/latest/reference/lang_data_string.html#heredocs).
32
32
  # A double-quoted string is subject to expression interpolation before the string
33
33
  # is parsed as an EPP template.
34
34
  #
@@ -6,7 +6,7 @@ module Puppet::Parser::Functions
6
6
  :arity => -2,
7
7
  :doc => <<-DOC
8
8
  Assigns classes to a node using an
9
- [array merge lookup](https://docs.puppetlabs.com/hiera/latest/lookup_types.htmlarray-merge)
9
+ [array merge lookup](https://docs.puppetlabs.com/hiera/latest/lookup_types.html#array-merge)
10
10
  that retrieves the value for a user-specified key from Hiera's data.
11
11
 
12
12
  The `hiera_include` function requires:
@@ -31,7 +31,7 @@ top of the hierarchy. This lets you temporarily modify the hierarchy for a singl
31
31
  searching the rest of the hierarchy.
32
32
 
33
33
  The function uses an
34
- [array merge lookup](https://docs.puppetlabs.com/hiera/latest/lookup_types.htmlarray-merge)
34
+ [array merge lookup](https://docs.puppetlabs.com/hiera/latest/lookup_types.html#array-merge)
35
35
  to retrieve the `classes` array, so every node gets every class from the hierarchy.
36
36
 
37
37
  **Example**: Using `hiera_include`
@@ -29,7 +29,7 @@ parameter tag without default values. Puppet produces an error if the
29
29
  `inline_epp` function fails to pass any required parameter.
30
30
 
31
31
  An inline EPP template should be written as a single-quoted string or
32
- [heredoc](puppet/latest/reference/lang_data_string.html#heredocs).
32
+ [heredoc](/puppet/latest/reference/lang_data_string.html#heredocs).
33
33
  A double-quoted string is subject to expression interpolation before the string
34
34
  is parsed as an EPP template.
35
35
 
@@ -183,7 +183,7 @@ module Types
183
183
  end
184
184
 
185
185
  def hash
186
- super.hash * 31 + key.hash
186
+ super.hash ^ key.hash
187
187
  end
188
188
  end
189
189
 
@@ -237,9 +237,7 @@ module Types
237
237
  end
238
238
 
239
239
  def hash
240
- hash = super.hash
241
- hash = hash * 31 + expected.hash
242
- hash * 31 + actual.hash
240
+ [canonical_path, expected, actual].hash
243
241
  end
244
242
 
245
243
  def swap_expected(expected)
@@ -324,7 +324,7 @@ class PTypeWithContainedType < PAnyType
324
324
  end
325
325
 
326
326
  def hash
327
- self.class.hash * 31 * @type.hash
327
+ self.class.hash ^ @type.hash
328
328
  end
329
329
 
330
330
  def eql?(o)
@@ -637,7 +637,7 @@ class PNumericType < PScalarType
637
637
  end
638
638
 
639
639
  def hash
640
- @from.hash * 31 + @to.hash
640
+ @from.hash ^ @to.hash
641
641
  end
642
642
 
643
643
  def eql?(o)
@@ -819,7 +819,7 @@ class PCollectionType < PAnyType
819
819
  end
820
820
 
821
821
  def hash
822
- @element_type.hash * 31 + @size_type.hash
822
+ @element_type.hash ^ @size_type.hash
823
823
  end
824
824
 
825
825
  def iterable?(guard = nil)
@@ -958,7 +958,7 @@ class PStringType < PScalarType
958
958
  end
959
959
 
960
960
  def hash
961
- @size_type.hash * 31 + @values.hash
961
+ @size_type.hash ^ @values.hash
962
962
  end
963
963
 
964
964
  def iterable?(guard = nil)
@@ -1151,7 +1151,7 @@ class PStructElement < TypedModelObject
1151
1151
  end
1152
1152
 
1153
1153
  def hash
1154
- value_type.hash * 31 + key_type.hash
1154
+ value_type.hash ^ key_type.hash
1155
1155
  end
1156
1156
 
1157
1157
  def name
@@ -1437,7 +1437,7 @@ class PTupleType < PAnyType
1437
1437
  end
1438
1438
 
1439
1439
  def hash
1440
- @size_type.hash * 31 + @types.hash
1440
+ @size_type.hash ^ @types.hash
1441
1441
  end
1442
1442
 
1443
1443
  def eql?(o)
@@ -1570,7 +1570,7 @@ class PCallableType < PAnyType
1570
1570
  end
1571
1571
 
1572
1572
  def hash
1573
- @param_types.hash * 31 + @block_type.hash
1573
+ @param_types.hash ^ @block_type.hash
1574
1574
  end
1575
1575
 
1576
1576
  def eql?(o)
@@ -1717,7 +1717,7 @@ class PHashType < PCollectionType
1717
1717
  end
1718
1718
 
1719
1719
  def hash
1720
- @key_type.hash * 31 + super
1720
+ super ^ @key_type.hash
1721
1721
  end
1722
1722
 
1723
1723
  def instance?(o)
@@ -2022,7 +2022,7 @@ class PRuntimeType < PAnyType
2022
2022
  end
2023
2023
 
2024
2024
  def hash
2025
- @runtime.hash * 31 + @runtime_type_name.hash
2025
+ @runtime.hash ^ @runtime_type_name.hash
2026
2026
  end
2027
2027
 
2028
2028
  def eql?(o)
@@ -2092,7 +2092,7 @@ class PHostClassType < PCatalogEntryType
2092
2092
  end
2093
2093
 
2094
2094
  def hash
2095
- 11 * @class_name.hash
2095
+ 11 ^ @class_name.hash
2096
2096
  end
2097
2097
  def eql?(o)
2098
2098
  self.class == o.class && @class_name == o.class_name
@@ -2124,7 +2124,7 @@ class PResourceType < PCatalogEntryType
2124
2124
  end
2125
2125
 
2126
2126
  def hash
2127
- @type_name.hash * 31 + @title.hash
2127
+ @type_name.hash ^ @title.hash
2128
2128
  end
2129
2129
 
2130
2130
  def eql?(o)
@@ -2212,7 +2212,7 @@ class PTypeReferenceType < PAnyType
2212
2212
  end
2213
2213
 
2214
2214
  def hash
2215
- @name.hash * 31 + @parameters.hash
2215
+ @name.hash ^ @parameters.hash
2216
2216
  end
2217
2217
 
2218
2218
  def eql?(o)
@@ -12,6 +12,8 @@ Puppet::Type.type(:package).provide :pip3,
12
12
  These options should be specified as a string (e.g. '--flag'), a hash (e.g. {'--flag' => 'value'}),
13
13
  or an array where each element is either a string or a hash."
14
14
 
15
+ has_feature :installable, :uninstallable, :upgradeable, :versionable, :install_options
16
+
15
17
  def self.cmd
16
18
  ["pip3"]
17
19
  end
@@ -91,7 +91,7 @@ providers = Puppet::Util::Reference.newreference :providers, :title => "Provider
91
91
 
92
92
  ret << markdown_header(type.name.to_s + "_", 2)
93
93
 
94
- ret << "[#{type.name}](https://docs.puppetlabs.com/references/stable/type.html##{type.name})\n\n"
94
+ ret << "[#{type.name}](https://docs.puppetlabs.com/puppet/latest/reference/type.html##{type.name})\n\n"
95
95
  ret << option("Default provider", default)
96
96
  ret << doctable(headers, table_data)
97
97
 
@@ -102,6 +102,9 @@ class Puppet::Resource::Catalog < Puppet::Graph::SimpleGraph
102
102
  end
103
103
  end
104
104
 
105
+ # Add `resources` to the catalog after `other`. WARNING: adding
106
+ # multiple resources will produce the reverse ordering, e.g. calling
107
+ # `add_resource_after(A, [B,C])` will result in `[A,C,B]`.
105
108
  def add_resource_after(other, *resources)
106
109
  resources.each do |resource|
107
110
  other_title_key = title_key_for_ref(other.ref)
@@ -111,7 +114,6 @@ class Puppet::Resource::Catalog < Puppet::Graph::SimpleGraph
111
114
  end
112
115
  end
113
116
 
114
-
115
117
  def add_resource(*resources)
116
118
  resources.each do |resource|
117
119
  add_one_resource(resource)
@@ -275,30 +275,6 @@ class Puppet::Transaction
275
275
  resource_status(resource).failed_dependencies = failed.to_a
276
276
  end
277
277
 
278
- # A general method for recursively generating new resources from a
279
- # resource.
280
- def generate_additional_resources(resource)
281
- return unless resource.respond_to?(:generate)
282
- begin
283
- made = resource.generate
284
- rescue => detail
285
- resource.log_exception(detail, "Failed to generate additional resources using 'generate': #{detail}")
286
- end
287
- return unless made
288
- made = [made] unless made.is_a?(Array)
289
- made.uniq.each do |res|
290
- begin
291
- res.tag(*resource.tags)
292
- @catalog.add_resource(res)
293
- res.finish
294
- add_conditional_directed_dependency(resource, res)
295
- generate_additional_resources(res)
296
- rescue Puppet::Resource::Catalog::DuplicateResourceError
297
- res.info "Duplicate generated resource; skipping"
298
- end
299
- end
300
- end
301
-
302
278
  # Should we ignore tags?
303
279
  def ignore_tags?
304
280
  ! @catalog.host_config?
@@ -1246,7 +1246,7 @@ class Type
1246
1246
  event _would_ have been sent.
1247
1247
 
1248
1248
  **Important note:**
1249
- [The `noop` setting](https://docs.puppetlabs.com/references/latest/configuration.html#noop)
1249
+ [The `noop` setting](https://docs.puppetlabs.com/puppet/latest/reference/configuration.html#noop)
1250
1250
  allows you to globally enable or disable noop mode, but it will _not_ override
1251
1251
  the `noop` metaparameter on individual resources. That is, the value of the
1252
1252
  global `noop` setting will _only_ affect resources that do not have an explicit
@@ -1266,7 +1266,7 @@ class Type
1266
1266
  The value of this metaparameter must be the `name` of a `schedule`
1267
1267
  resource. This means you must declare a schedule resource, then
1268
1268
  refer to it by name; see
1269
- [the docs for the `schedule` type](https://docs.puppetlabs.com/references/latest/type.html#schedule)
1269
+ [the docs for the `schedule` type](https://docs.puppetlabs.com/puppet/latest/reference/type.html#schedule)
1270
1270
  for more info.
1271
1271
 
1272
1272
  schedule { 'everyday':
@@ -1441,7 +1441,7 @@ class Type
1441
1441
  }
1442
1442
 
1443
1443
  Tags are useful for things like applying a subset of a host's configuration
1444
- with [the `tags` setting](/references/latest/configuration.html#tags)
1444
+ with [the `tags` setting](/puppet/latest/reference/configuration.html#tags)
1445
1445
  (e.g. `puppet agent --test --tags bootstrap`)."
1446
1446
 
1447
1447
  munge do |tags|
@@ -1630,7 +1630,7 @@ class Type
1630
1630
  By default, all classes are declared in the `main` stage. To assign a class
1631
1631
  to a different stage, you must:
1632
1632
 
1633
- * Declare the new stage as a [`stage` resource](https://docs.puppetlabs.com/references/latest/type.html#stage).
1633
+ * Declare the new stage as a [`stage` resource](https://docs.puppetlabs.com/puppet/latest/reference/type.html#stage).
1634
1634
  * Declare an order relationship between the new stage and the `main` stage.
1635
1635
  * Use the resource-like syntax to declare the class, and set the `stage`
1636
1636
  metaparameter to the name of the desired stage.
@@ -236,11 +236,9 @@ Puppet::Type.newtype(:file) do
236
236
 
237
237
  newparam(:links) do
238
238
  desc "How to handle links during file actions. During file copying,
239
- `follow` will copy the target file instead of the link, `manage`
240
- will copy the link itself, and `ignore` will just pass it by.
241
- When not copying, `manage` and `ignore` behave equivalently
242
- (because you cannot really ignore links entirely during local
243
- recursion), and `follow` will manage the file to which the link points."
239
+ `follow` will copy the target file instead of the link and `manage`
240
+ will copy the link itself. When not copying, `manage` will manage
241
+ the link, and `follow` will manage the file to which the link points."
244
242
 
245
243
  newvalues(:follow, :manage)
246
244
 
@@ -35,8 +35,8 @@ module Puppet
35
35
  }
36
36
 
37
37
  ...but for larger files, this attribute is more useful when combined with the
38
- [template](https://docs.puppetlabs.com/references/latest/function.html#template)
39
- or [file](https://docs.puppetlabs.com/references/latest/function.html#file)
38
+ [template](https://docs.puppetlabs.com/puppet/latest/reference/function.html#template)
39
+ or [file](https://docs.puppetlabs.com/puppet/latest/reference/function.html#file)
40
40
  function.
41
41
  EOT
42
42
 
@@ -21,7 +21,7 @@ module Puppet
21
21
  puppet master's filebucket with the _desired_ content for each file,
22
22
  then instructs the agent to retrieve the content for a specific
23
23
  checksum. For more details,
24
- [see the `static_compiler` section in the catalog indirection docs](https://docs.puppetlabs.com/references/latest/indirection.html#catalog).
24
+ [see the `static_compiler` section in the catalog indirection docs](https://docs.puppetlabs.com/puppet/latest/reference/indirection.html#catalog).
25
25
 
26
26
  To use a central filebucket for backups, you will usually want to declare
27
27
  a filebucket resource and a resource default for the `backup` attribute
@@ -2,7 +2,7 @@ module Puppet
2
2
  Type.newtype(:schedule) do
3
3
  @doc = <<-'EOT'
4
4
  Define schedules for Puppet. Resources can be limited to a schedule by using the
5
- [`schedule`](https://docs.puppetlabs.com/references/latest/metaparameter.html#schedule)
5
+ [`schedule`](https://docs.puppetlabs.com/puppet/latest/reference/metaparameter.html#schedule)
6
6
  metaparameter.
7
7
 
8
8
  Currently, **schedules can only be used to stop a resource from being
@@ -2,7 +2,7 @@ Puppet::Type.newtype(:stage) do
2
2
  desc "A resource type for creating new run stages. Once a stage is available,
3
3
  classes can be assigned to it by declaring them with the resource-like syntax
4
4
  and using
5
- [the `stage` metaparameter](https://docs.puppetlabs.com/references/latest/metaparameter.html#stage).
5
+ [the `stage` metaparameter](https://docs.puppetlabs.com/puppet/latest/reference/metaparameter.html#stage).
6
6
 
7
7
  Note that new stages are not useful unless you also declare their order
8
8
  in relation to the default `main` stage.
@@ -7,7 +7,7 @@
7
7
 
8
8
 
9
9
  module Puppet
10
- PUPPETVERSION = '4.4.0'
10
+ PUPPETVERSION = '4.4.1'
11
11
 
12
12
  ##
13
13
  # version is a public API method intended to always provide a fast and
@@ -58,27 +58,6 @@ describe "Data binding" do
58
58
  Puppet[:modulepath] = dir
59
59
  end
60
60
 
61
- it "works with the puppet backend configured, although it can't use it for lookup" do
62
- configure_hiera_for_puppet
63
- create_manifest_in_module("testing", "binding.pp",
64
- <<-MANIFEST)
65
- # lookup via the puppet backend to ensure it works
66
- class testing::binding($value = hiera('variable')) {}
67
- MANIFEST
68
-
69
- create_manifest_in_module("testing", "data.pp",
70
- <<-MANIFEST)
71
- class testing::data (
72
- $variable = "the value"
73
- ) { }
74
- MANIFEST
75
-
76
- catalog = compile_to_catalog("include testing::data")
77
- resource = catalog.resource('Class[testing::data]')
78
-
79
- expect(resource[:variable]).to eq("the value")
80
- end
81
-
82
61
  context "with testing::binding and global data only" do
83
62
  it "looks up global data from hiera" do
84
63
  configure_hiera_for_one_tier(data)
@@ -205,19 +184,6 @@ describe "Data binding" do
205
184
  Puppet[:hiera_config] = hiera_config_file
206
185
  end
207
186
 
208
- def configure_hiera_for_puppet
209
- hiera_config_file = tmpfile("hiera.yaml")
210
-
211
- File.open(hiera_config_file, 'w') do |f|
212
- f.write("---
213
- :logger: 'noop'
214
- :backends: ['puppet']
215
- ")
216
- end
217
-
218
- Puppet[:hiera_config] = hiera_config_file
219
- end
220
-
221
187
  def create_manifest_in_module(module_name, name, manifest)
222
188
  module_dir = File.join(dir, module_name, 'manifests')
223
189
  FileUtils.mkdir_p(module_dir)
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
 
4
4
  require 'puppet/application/inspect'
5
5
  require 'puppet/resource/catalog'
6
- require 'puppet/indirector/catalog/yaml'
6
+ require 'puppet/indirector/catalog/json'
7
7
  require 'puppet/indirector/report/rest'
8
8
  require 'puppet/indirector/file_bucket_file/rest'
9
9
 
@@ -31,6 +31,17 @@ describe Puppet::Application::Inspect do
31
31
  Puppet[:report] = false
32
32
  expect { @inspect.setup }.to raise_error(/report=true/)
33
33
  end
34
+
35
+ it "should default to the json terminus class when catalog_cache_terminus is not set" do
36
+ Puppet::Resource::Catalog.indirection.expects(:terminus_class=).with(:json)
37
+ expect { @inspect.setup }.not_to raise_error
38
+ end
39
+
40
+ it "should respect the catalog_cache_terminus if set" do
41
+ Puppet[:catalog_cache_terminus] = :yaml
42
+ Puppet::Resource::Catalog.indirection.expects(:terminus_class=).with(:yaml)
43
+ expect { @inspect.setup }.not_to raise_error
44
+ end
34
45
  end
35
46
 
36
47
  describe "when executing", :uses_checksums => true do
@@ -42,13 +53,13 @@ describe Puppet::Application::Inspect do
42
53
  end
43
54
 
44
55
  it "should retrieve the local catalog" do
45
- Puppet::Resource::Catalog::Yaml.any_instance.expects(:find).with {|request| request.key == Puppet[:certname] }.returns(Puppet::Resource::Catalog.new)
56
+ Puppet::Resource::Catalog::Json.any_instance.expects(:find).with {|request| request.key == Puppet[:certname] }.returns(Puppet::Resource::Catalog.new)
46
57
 
47
58
  @inspect.run_command
48
59
  end
49
60
 
50
61
  it "should save the report to REST" do
51
- Puppet::Resource::Catalog::Yaml.any_instance.stubs(:find).returns(Puppet::Resource::Catalog.new)
62
+ Puppet::Resource::Catalog::Json.any_instance.stubs(:find).returns(Puppet::Resource::Catalog.new)
52
63
  Puppet::Transaction::Report::Rest.any_instance.expects(:save).with {|request| request.instance.host == Puppet[:certname] }
53
64
 
54
65
  @inspect.run_command
@@ -63,7 +74,7 @@ describe Puppet::Application::Inspect do
63
74
  file.close
64
75
  resource = Puppet::Resource.new(:file, file.path, :parameters => {:audit => "all"})
65
76
  catalog.add_resource(resource)
66
- Puppet::Resource::Catalog::Yaml.any_instance.stubs(:find).returns(catalog)
77
+ Puppet::Resource::Catalog::Json.any_instance.stubs(:find).returns(catalog)
67
78
 
68
79
  events = nil
69
80
 
@@ -87,7 +98,7 @@ describe Puppet::Application::Inspect do
87
98
  file = Tempfile.new("foo")
88
99
  resource = Puppet::Resource.new(:file, file.path, :parameters => {:audit => "all"})
89
100
  catalog.add_resource(resource)
90
- Puppet::Resource::Catalog::Yaml.any_instance.stubs(:find).returns(catalog)
101
+ Puppet::Resource::Catalog::Json.any_instance.stubs(:find).returns(catalog)
91
102
 
92
103
  events = nil
93
104
 
@@ -109,7 +120,7 @@ describe Puppet::Application::Inspect do
109
120
  file.close
110
121
  file.delete
111
122
  catalog.add_resource(resource)
112
- Puppet::Resource::Catalog::Yaml.any_instance.stubs(:find).returns(catalog)
123
+ Puppet::Resource::Catalog::Json.any_instance.stubs(:find).returns(catalog)
113
124
 
114
125
  events = nil
115
126
 
@@ -130,7 +141,7 @@ describe Puppet::Application::Inspect do
130
141
  Puppet[:archive_files] = true
131
142
  Puppet[:archive_file_server] = "filebucketserver"
132
143
  @catalog = Puppet::Resource::Catalog.new
133
- Puppet::Resource::Catalog::Yaml.any_instance.stubs(:find).returns(@catalog)
144
+ Puppet::Resource::Catalog::Json.any_instance.stubs(:find).returns(@catalog)
134
145
  end
135
146
 
136
147
  describe "when auditing files" do
@@ -236,7 +247,7 @@ describe Puppet::Application::Inspect do
236
247
  end
237
248
 
238
249
  @catalog = Puppet::Resource::Catalog.new
239
- Puppet::Resource::Catalog::Yaml.any_instance.stubs(:find).returns(@catalog)
250
+ Puppet::Resource::Catalog::Json.any_instance.stubs(:find).returns(@catalog)
240
251
 
241
252
  Puppet::Transaction::Report::Rest.any_instance.expects(:save).with do |request|
242
253
  @report = request.instance
@@ -4,31 +4,41 @@ require 'puppet'
4
4
  require 'puppet/data_providers/hiera_config'
5
5
  require 'puppet/data_providers/hiera_interpolate'
6
6
 
7
- describe "Puppet::DataProviders::HieraInterpolate" do
7
+ describe 'Puppet::DataProviders::HieraInterpolate' do
8
8
 
9
9
  let(:interpolator) { Class.new { include Puppet::DataProviders::HieraInterpolate }.new }
10
10
  let(:scope) { {} }
11
11
  let(:lookup_invocation) { Puppet::Pops::Lookup::Invocation.new(scope, {}, {}, nil) }
12
12
 
13
+ def expect_lookup(*keys)
14
+ keys.each { |key| Puppet::Pops::Lookup.expects(:lookup).with(key, nil, '', true, nil, lookup_invocation).returns(data[key]) }
15
+ end
16
+
13
17
  context 'when interpolating nested data' do
14
- let(:nested_hash) { { 'a' => { 'aa' => "%{alias('aaa')}" } } }
18
+ let(:nested_hash) { {'a' => {'aa' => "%{alias('aaa')}"}} }
19
+
20
+ let(:data) {
21
+ {
22
+ 'aaa' => {'b' => {'bb' => "%{alias('bbb')}"}},
23
+ 'bbb' => ["%{alias('ccc')}"],
24
+ 'ccc' => 'text'
25
+ }
26
+ }
15
27
 
16
28
  it 'produces a nested hash with arrays from nested aliases with hashes and arrays' do
17
- Puppet::Pops::Lookup.expects(:lookup).with('aaa', nil, '', true, nil, lookup_invocation).returns({ 'b' => { 'bb' => "%{alias('bbb')}" } })
18
- Puppet::Pops::Lookup.expects(:lookup).with('bbb', nil, '', true, nil, lookup_invocation).returns([ "%{alias('ccc')}" ])
19
- Puppet::Pops::Lookup.expects(:lookup).with('ccc', nil, '', true, nil, lookup_invocation).returns('text')
20
- expect(interpolator.interpolate(nested_hash, lookup_invocation, true)).to eq('a'=>{'aa'=>{'b'=>{'bb'=>['text']}}})
29
+ expect_lookup('aaa', 'bbb', 'ccc')
30
+ expect(interpolator.interpolate(nested_hash, lookup_invocation, true)).to eq('a' => {'aa' => {'b' => {'bb' => ['text']}}})
21
31
  end
22
32
  end
23
33
 
24
34
  context 'when there are empty interpolations %{} in data' do
25
35
 
26
- let(:empty_interpolation) {'clown%{}shoe'}
27
- let(:empty_interpolation_as_escape) {'clown%%{}{shoe}s'}
28
- let(:only_empty_interpolation) {'%{}'}
29
- let(:empty_namespace) {'%{::}'}
30
- let(:whitespace1) {'%{ :: }'}
31
- let(:whitespace2) {'%{ }'}
36
+ let(:empty_interpolation) { 'clown%{}shoe' }
37
+ let(:empty_interpolation_as_escape) { 'clown%%{}{shoe}s' }
38
+ let(:only_empty_interpolation) { '%{}' }
39
+ let(:empty_namespace) { '%{::}' }
40
+ let(:whitespace1) { '%{ :: }' }
41
+ let(:whitespace2) { '%{ }' }
32
42
 
33
43
  it 'should produce an empty string for the interpolation' do
34
44
  expect(interpolator.interpolate(empty_interpolation, lookup_invocation, true)).to eq('clownshoe')
@@ -54,4 +64,242 @@ describe "Puppet::DataProviders::HieraInterpolate" do
54
64
  expect(interpolator.interpolate(whitespace2, lookup_invocation, true)).to eq('')
55
65
  end
56
66
  end
67
+
68
+ context 'when there are quoted empty interpolations %{} in data' do
69
+
70
+ let(:empty_interpolation) { 'clown%{""}shoe' }
71
+ let(:empty_interpolation_as_escape) { 'clown%%{""}{shoe}s' }
72
+ let(:only_empty_interpolation) { '%{""}' }
73
+ let(:empty_namespace) { '%{"::"}' }
74
+ let(:whitespace1) { '%{ "::" }' }
75
+ let(:whitespace2) { '%{ "" }' }
76
+
77
+ it 'should produce an empty string for the interpolation' do
78
+ expect(interpolator.interpolate(empty_interpolation, lookup_invocation, true)).to eq('clownshoe')
79
+ end
80
+
81
+ it 'the empty interpolation can be used as an escape mechanism' do
82
+ expect(interpolator.interpolate(empty_interpolation_as_escape, lookup_invocation, true)).to eq('clown%{shoe}s')
83
+ end
84
+
85
+ it 'the value can consist of only an empty escape' do
86
+ expect(interpolator.interpolate(only_empty_interpolation, lookup_invocation, true)).to eq('')
87
+ end
88
+
89
+ it 'the value can consist of an empty namespace %{"::"}' do
90
+ expect(interpolator.interpolate(empty_namespace, lookup_invocation, true)).to eq('')
91
+ end
92
+
93
+ it 'the value can consist of whitespace %{ "::" }' do
94
+ expect(interpolator.interpolate(whitespace1, lookup_invocation, true)).to eq('')
95
+ end
96
+
97
+ it 'the value can consist of whitespace %{ "" }' do
98
+ expect(interpolator.interpolate(whitespace2, lookup_invocation, true)).to eq('')
99
+ end
100
+ end
101
+
102
+
103
+ context 'when using dotted keys' do
104
+ let(:data) {
105
+ {
106
+ 'a.b' => '(lookup) a dot b',
107
+ 'a' => {
108
+ 'd' => '(lookup) a dot d is a hash entry',
109
+ 'd.x' => '(lookup) a dot d.x is a hash entry',
110
+ 'd.z' => {
111
+ 'g' => '(lookup) a dot d.z dot g is a hash entry'}
112
+ },
113
+ 'a.x' => {
114
+ 'd' => '(lookup) a.x dot d is a hash entry',
115
+ 'd.x' => '(lookup) a.x dot d.x is a hash entry',
116
+ 'd.z' => {
117
+ 'g' => '(lookup) a.x dot d.z dot g is a hash entry'
118
+ }
119
+ },
120
+ 'x.1' => '(lookup) x dot 1',
121
+ }
122
+ }
123
+
124
+ let(:scope) {
125
+ {
126
+ 'a.b' => '(scope) a dot b',
127
+ 'a' => {
128
+ 'd' => '(scope) a dot d is a hash entry',
129
+ 'd.x' => '(scope) a dot d.x is a hash entry',
130
+ 'd.z' => {
131
+ 'g' => '(scope) a dot d.z dot g is a hash entry'}
132
+ },
133
+ 'a.x' => {
134
+ 'd' => '(scope) a.x dot d is a hash entry',
135
+ 'd.x' => '(scope) a.x dot d.x is a hash entry',
136
+ 'd.z' => {
137
+ 'g' => '(scope) a.x dot d.z dot g is a hash entry'
138
+ }
139
+ },
140
+ 'x.1' => '(scope) x dot 1',
141
+ }
142
+ }
143
+
144
+ it 'should find an entry using a quoted interpolation' do
145
+ expect(interpolator.interpolate("a dot c: %{'a.b'}", lookup_invocation, true)).to eq('a dot c: (scope) a dot b')
146
+ end
147
+
148
+ it 'should find an entry using a quoted interpolation with method lookup' do
149
+ expect_lookup('a.b')
150
+ expect(interpolator.interpolate("a dot c: %{lookup(\"'a.b'\")}", lookup_invocation, true)).to eq('a dot c: (lookup) a dot b')
151
+ end
152
+
153
+ it 'should find an entry using a quoted interpolation with method alias' do
154
+ expect_lookup('a.b')
155
+ expect(interpolator.interpolate("%{alias(\"'a.b'\")}", lookup_invocation, true)).to eq('(lookup) a dot b')
156
+ end
157
+
158
+ it 'should use a dotted key to navigate into a structure when it is not quoted' do
159
+ expect(interpolator.interpolate('a dot e: %{a.d}', lookup_invocation, true)).to eq('a dot e: (scope) a dot d is a hash entry')
160
+ end
161
+
162
+ it 'should use a dotted key to navigate into a structure when when it is not quoted with method lookup' do
163
+ expect_lookup('a')
164
+ expect(interpolator.interpolate("a dot e: %{lookup('a.d')}", lookup_invocation, true)).to eq('a dot e: (lookup) a dot d is a hash entry')
165
+ end
166
+
167
+ it 'should use a mix of quoted and dotted keys to navigate into a structure containing dotted keys and quoted key is last' do
168
+ expect(interpolator.interpolate("a dot ex: %{a.'d.x'}", lookup_invocation, true)).to eq('a dot ex: (scope) a dot d.x is a hash entry')
169
+ end
170
+
171
+ it 'should use a mix of quoted and dotted keys to navigate into a structure containing dotted keys and quoted key is last and method is lookup' do
172
+ expect_lookup('a')
173
+ expect(interpolator.interpolate("a dot ex: %{lookup(\"a.'d.x'\")}", lookup_invocation, true)).to eq('a dot ex: (lookup) a dot d.x is a hash entry')
174
+ end
175
+
176
+ it 'should use a mix of quoted and dotted keys to navigate into a structure containing dotted keys and quoted key is first' do
177
+ expect(interpolator.interpolate("a dot xe: %{'a.x'.d}", lookup_invocation, true)).to eq('a dot xe: (scope) a.x dot d is a hash entry')
178
+ end
179
+
180
+ it 'should use a mix of quoted and dotted keys to navigate into a structure containing dotted keys and quoted key is first and method is lookup' do
181
+ expect_lookup('a.x')
182
+ expect(interpolator.interpolate("a dot xe: %{lookup(\"'a.x'.d\")}", lookup_invocation, true)).to eq('a dot xe: (lookup) a.x dot d is a hash entry')
183
+ end
184
+
185
+ it 'should use a mix of quoted and dotted keys to navigate into a structure containing dotted keys and quoted key is in the middle' do
186
+ expect(interpolator.interpolate("a dot xm: %{a.'d.z'.g}", lookup_invocation, true)).to eq('a dot xm: (scope) a dot d.z dot g is a hash entry')
187
+ end
188
+
189
+ it 'should use a mix of quoted and dotted keys to navigate into a structure containing dotted keys and quoted key is in the middle and method is lookup' do
190
+ expect_lookup('a')
191
+ expect(interpolator.interpolate("a dot xm: %{lookup(\"a.'d.z'.g\")}", lookup_invocation, true)).to eq('a dot xm: (lookup) a dot d.z dot g is a hash entry')
192
+ end
193
+
194
+ it 'should use a mix of several quoted and dotted keys to navigate into a structure containing dotted keys and quoted key is in the middle' do
195
+ expect(interpolator.interpolate("a dot xx: %{'a.x'.'d.z'.g}", lookup_invocation, true)).to eq('a dot xx: (scope) a.x dot d.z dot g is a hash entry')
196
+ end
197
+
198
+ it 'should use a mix of several quoted and dotted keys to navigate into a structure containing dotted keys and quoted key is in the middle and method is lookup' do
199
+ expect_lookup('a.x')
200
+ expect(interpolator.interpolate("a dot xx: %{lookup(\"'a.x'.'d.z'.g\")}", lookup_invocation, true)).to eq('a dot xx: (lookup) a.x dot d.z dot g is a hash entry')
201
+ end
202
+
203
+ it 'should find an entry using using a quoted interpolation on dotted key containing numbers' do
204
+ expect(interpolator.interpolate("x dot 2: %{'x.1'}", lookup_invocation, true)).to eq('x dot 2: (scope) x dot 1')
205
+ end
206
+
207
+ it 'should find an entry using using a quoted interpolation on dotted key containing numbers using method lookup' do
208
+ expect_lookup('x.1')
209
+ expect(interpolator.interpolate("x dot 2: %{lookup(\"'x.1'\")}", lookup_invocation, true)).to eq('x dot 2: (lookup) x dot 1')
210
+ end
211
+
212
+ it 'should not find a subkey when the dotted key is quoted' do
213
+ expect(interpolator.interpolate("a dot f: %{'a.d'}", lookup_invocation, true)).to eq('a dot f: ')
214
+ end
215
+
216
+ it 'should not find a subkey when the dotted key is quoted with method lookup' do
217
+ expect_lookup('a.d')
218
+ expect(interpolator.interpolate("a dot f: %{lookup(\"'a.d'\")}", lookup_invocation, true)).to eq('a dot f: ')
219
+ end
220
+ end
221
+
222
+ context 'when dealing with non alphanumeric characters' do
223
+ let(:data) {
224
+ {
225
+ 'a key with whitespace' => 'value for a ws key',
226
+ 'ws_key' => '%{alias("a key with whitespace")}',
227
+ '\#@!&%|' => 'not happy',
228
+ 'angry' => '%{alias("\#@!&%|")}',
229
+ '!$\%!' => {
230
+ '\#@!&%|' => 'not happy at all'
231
+ },
232
+ 'very_angry' => '%{alias("!$\%!.\#@!&%|")}',
233
+ 'a key with' => {
234
+ 'nested whitespace' => 'value for nested ws key',
235
+ ' untrimmed whitespace ' => 'value for untrimmed ws key'
236
+ }
237
+ }
238
+ }
239
+
240
+ it 'allows keys with white space' do
241
+ expect_lookup('ws_key', 'a key with whitespace')
242
+ expect(interpolator.interpolate("%{lookup('ws_key')}", lookup_invocation, true)).to eq('value for a ws key')
243
+ end
244
+
245
+ it 'allows keys with non alphanumeric characters' do
246
+ expect_lookup('angry', '\#@!&%|')
247
+ expect(interpolator.interpolate("%{lookup('angry')}", lookup_invocation, true)).to eq('not happy')
248
+ end
249
+
250
+ it 'allows dotted keys with non alphanumeric characters' do
251
+ expect_lookup('very_angry', '!$\%!')
252
+ expect(interpolator.interpolate("%{lookup('very_angry')}", lookup_invocation, true)).to eq('not happy at all')
253
+ end
254
+
255
+ it 'allows dotted keys with nested white space' do
256
+ expect_lookup('a key with')
257
+ expect(interpolator.interpolate("%{lookup('a key with.nested whitespace')}", lookup_invocation, true)).to eq('value for nested ws key')
258
+ end
259
+
260
+ it 'will trim each key element' do
261
+ expect_lookup('a key with')
262
+ expect(interpolator.interpolate("%{lookup(' a key with . nested whitespace ')}", lookup_invocation, true)).to eq('value for nested ws key')
263
+ end
264
+
265
+ it 'will not trim quoted key element' do
266
+ expect_lookup('a key with')
267
+ expect(interpolator.interpolate("%{lookup(' a key with .\" untrimmed whitespace \"')}", lookup_invocation, true)).to eq('value for untrimmed ws key')
268
+ end
269
+
270
+ it 'will not trim spaces outside of quoted key element' do
271
+ expect_lookup('a key with')
272
+ expect(interpolator.interpolate("%{lookup(' a key with . \" untrimmed whitespace \" ')}", lookup_invocation, true)).to eq('value for untrimmed ws key')
273
+ end
274
+ end
275
+
276
+ context 'when dealing with bad keys' do
277
+ it 'should produce an error when different quotes are used on either side' do
278
+ expect { interpolator.interpolate("%{'the.key\"}", lookup_invocation, true)}.to raise_error("Syntax error in string: %{'the.key\"}")
279
+ end
280
+
281
+ it 'should produce an if there is only one quote' do
282
+ expect { interpolator.interpolate("%{the.'key}", lookup_invocation, true)}.to raise_error("Syntax error in string: %{the.'key}")
283
+ end
284
+
285
+ it 'should produce an error for an empty segment' do
286
+ expect { interpolator.interpolate('%{the..key}', lookup_invocation, true)}.to raise_error("Syntax error in string: %{the..key}")
287
+ end
288
+
289
+ it 'should produce an error for an empty quoted segment' do
290
+ expect { interpolator.interpolate("%{the.''.key}", lookup_invocation, true)}.to raise_error("Syntax error in string: %{the.''.key}")
291
+ end
292
+
293
+ it 'should produce an error for an partly quoted segment' do
294
+ expect { interpolator.interpolate("%{the.'pa'key}", lookup_invocation, true)}.to raise_error("Syntax error in string: %{the.'pa'key}")
295
+ end
296
+
297
+ it 'should produce an error when different quotes are used on either side in a method argument' do
298
+ expect { interpolator.interpolate("%{lookup('the.key\")}", lookup_invocation, true)}.to raise_error("Syntax error in string: %{lookup('the.key\")}")
299
+ end
300
+
301
+ it 'should produce an error unless a known interpolation method is used' do
302
+ expect { interpolator.interpolate("%{flubber(\"hello\")}", lookup_invocation, true)}.to raise_error("Unknown interpolation method 'flubber'")
303
+ end
304
+ end
57
305
  end
@@ -15,6 +15,14 @@ describe provider_class do
15
15
  XMLRPC::Client.stubs(:new2).returns(@client)
16
16
  end
17
17
 
18
+ describe 'provider features' do
19
+ it { is_expected.to be_installable }
20
+ it { is_expected.to be_uninstallable }
21
+ it { is_expected.to be_upgradeable }
22
+ it { is_expected.to be_versionable }
23
+ it { is_expected.to be_install_options }
24
+ end
25
+
18
26
  describe "parse" do
19
27
 
20
28
  it "should return a hash on valid input" do
@@ -14,6 +14,14 @@ describe provider_class do
14
14
  @client.stubs(:call).with('package_releases', 'fake_package').returns([])
15
15
  end
16
16
 
17
+ describe 'provider features' do
18
+ it { is_expected.to be_installable }
19
+ it { is_expected.to be_uninstallable }
20
+ it { is_expected.to be_upgradeable }
21
+ it { is_expected.to be_versionable }
22
+ it { is_expected.to be_install_options }
23
+ end
24
+
17
25
  describe "parse" do
18
26
 
19
27
  it "should return a hash on valid input" do
@@ -42,7 +42,7 @@ describe Puppet::Type.type(:service).provider(:systemd) do
42
42
  end
43
43
  end
44
44
 
45
- [ 17, 18, 19, 20, 21 ].each do |ver|
45
+ [ 17, 18, 19, 20, 21, 22, 23 ].each do |ver|
46
46
  it "should be the default provider on fedora#{ver}" do
47
47
  Facter.stubs(:value).with(:osfamily).returns(:redhat)
48
48
  Facter.stubs(:value).with(:operatingsystem).returns(:fedora)
@@ -296,6 +296,7 @@ describe Puppet::Resource::Catalog, "when compiling" do
296
296
  @catalog = Puppet::Resource::Catalog.new("host")
297
297
  @one = Puppet::Type.type(:notify).new :name => "one"
298
298
  @two = Puppet::Type.type(:notify).new :name => "two"
299
+ @three = Puppet::Type.type(:notify).new :name => "three"
299
300
  @dupe = Puppet::Type.type(:notify).new :name => "one"
300
301
  end
301
302
 
@@ -349,6 +350,32 @@ describe Puppet::Resource::Catalog, "when compiling" do
349
350
  expect(@catalog.resource("notify[one]", nil)).to equal(@one)
350
351
  end
351
352
 
353
+ it "adds resources before an existing resource" do
354
+ @catalog.add_resource(@one)
355
+ @catalog.add_resource_before(@one, @two, @three)
356
+
357
+ expect(@catalog.resources).to eq([@two, @three, @one])
358
+ end
359
+
360
+ it "raises if adding a resource before a resource not in the catalog" do
361
+ expect {
362
+ @catalog.add_resource_before(@one, @two)
363
+ }.to raise_error(ArgumentError, "Cannot add resource Notify[two] before Notify[one] because Notify[one] is not yet in the catalog")
364
+ end
365
+
366
+ it "adds resources after an existing resource in reverse order" do
367
+ @catalog.add_resource(@one)
368
+ @catalog.add_resource_after(@one, @two, @three)
369
+
370
+ expect(@catalog.resources).to eq([@one, @three, @two])
371
+ end
372
+
373
+ it "raises if adding a resource after a resource not in the catalog" do
374
+ expect {
375
+ @catalog.add_resource_after(@one, @two)
376
+ }.to raise_error(ArgumentError, "Cannot add resource Notify[two] after Notify[one] because Notify[one] is not yet in the catalog")
377
+ end
378
+
352
379
  describe 'with a duplicate resource' do
353
380
  def resource_at(type, name, file, line)
354
381
  resource = Puppet::Resource.new(type, name)
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: 4.4.0
4
+ version: 4.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet Labs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-11 00:00:00.000000000 Z
11
+ date: 2016-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: facter
@@ -1382,7 +1382,6 @@ files:
1382
1382
  - ext/osx/prototype.plist.erb
1383
1383
  - ext/osx/puppet.plist
1384
1384
  - ext/project_data.yaml
1385
- - ext/puppet-nm-dispatcher
1386
1385
  - ext/puppet-test
1387
1386
  - ext/puppetlisten/puppetlisten.rb
1388
1387
  - ext/puppetlisten/puppetrun.rb
@@ -1,13 +0,0 @@
1
- #!/bin/bash
2
- #
3
- # Restart puppet on network changes to pickup changes to /etc/resolv.conf
4
- #
5
- # https://projects.puppetlabs.com/issues/2776
6
- # https://bugzilla.redhat.com/532085
7
-
8
-
9
- if [ -f "/bin/systemctl" ] ; then
10
- [[ $2 =~ ^(up|down)$ ]] && /bin/systemctl try-restart puppet.service || :
11
- else
12
- [[ $2 =~ ^(up|down)$ ]] && /sbin/service puppet condrestart || :
13
- fi