puppet 4.10.4 → 4.10.5

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 (70) hide show
  1. checksums.yaml +7 -0
  2. data/lib/puppet/application/lookup.rb +2 -2
  3. data/lib/puppet/configurer/fact_handler.rb +1 -1
  4. data/lib/puppet/face/epp.rb +26 -24
  5. data/lib/puppet/file_serving/metadata.rb +2 -2
  6. data/lib/puppet/forge.rb +5 -3
  7. data/lib/puppet/forge/cache.rb +1 -0
  8. data/lib/puppet/forge/repository.rb +2 -1
  9. data/lib/puppet/indirector/catalog/compiler.rb +4 -3
  10. data/lib/puppet/indirector/request.rb +9 -8
  11. data/lib/puppet/module.rb +30 -0
  12. data/lib/puppet/network/http/rack/rest.rb +2 -1
  13. data/lib/puppet/parser/compiler.rb +4 -0
  14. data/lib/puppet/parser/functions/assert_type.rb +1 -1
  15. data/lib/puppet/parser/functions/binary_file.rb +1 -1
  16. data/lib/puppet/parser/functions/break.rb +1 -1
  17. data/lib/puppet/parser/functions/defined.rb +1 -1
  18. data/lib/puppet/parser/functions/dig.rb +1 -1
  19. data/lib/puppet/parser/functions/each.rb +1 -1
  20. data/lib/puppet/parser/functions/epp.rb +1 -1
  21. data/lib/puppet/parser/functions/filter.rb +1 -1
  22. data/lib/puppet/parser/functions/find_file.rb +1 -1
  23. data/lib/puppet/parser/functions/inline_epp.rb +1 -1
  24. data/lib/puppet/parser/functions/lest.rb +1 -1
  25. data/lib/puppet/parser/functions/map.rb +1 -1
  26. data/lib/puppet/parser/functions/match.rb +1 -1
  27. data/lib/puppet/parser/functions/new.rb +1 -1
  28. data/lib/puppet/parser/functions/next.rb +1 -1
  29. data/lib/puppet/parser/functions/reduce.rb +1 -1
  30. data/lib/puppet/parser/functions/return.rb +1 -1
  31. data/lib/puppet/parser/functions/reverse_each.rb +1 -1
  32. data/lib/puppet/parser/functions/slice.rb +1 -1
  33. data/lib/puppet/parser/functions/step.rb +1 -1
  34. data/lib/puppet/parser/functions/strftime.rb +1 -1
  35. data/lib/puppet/parser/functions/then.rb +1 -1
  36. data/lib/puppet/parser/functions/type.rb +1 -1
  37. data/lib/puppet/parser/functions/with.rb +1 -1
  38. data/lib/puppet/pops/evaluator/collector_transformer.rb +2 -2
  39. data/lib/puppet/pops/evaluator/collectors/catalog_collector.rb +2 -2
  40. data/lib/puppet/pops/evaluator/collectors/exported_collector.rb +2 -2
  41. data/lib/puppet/pops/merge_strategy.rb +1 -1
  42. data/lib/puppet/provider/nameservice.rb +4 -2
  43. data/lib/puppet/reports/http.rb +4 -2
  44. data/lib/puppet/resource/capability_finder.rb +1 -1
  45. data/lib/puppet/type/file/source.rb +9 -3
  46. data/lib/puppet/util.rb +122 -2
  47. data/lib/puppet/util/execution.rb +1 -1
  48. data/lib/puppet/util/rdoc/generators/puppet_generator.rb +1 -1
  49. data/lib/puppet/version.rb +1 -1
  50. data/locales/puppet.pot +12 -4
  51. data/spec/integration/application/apply_spec.rb +10 -0
  52. data/spec/integration/type/file_spec.rb +29 -0
  53. data/spec/integration/util/execution_spec.rb +8 -0
  54. data/spec/unit/application/lookup_spec.rb +1 -1
  55. data/spec/unit/configurer/fact_handler_spec.rb +30 -8
  56. data/spec/unit/face/epp_face_spec.rb +9 -0
  57. data/spec/unit/file_serving/metadata_spec.rb +21 -0
  58. data/spec/unit/forge/forge_spec.rb +112 -0
  59. data/spec/unit/forge/repository_spec.rb +4 -4
  60. data/spec/unit/functions/lookup_spec.rb +26 -0
  61. data/spec/unit/indirector/catalog/compiler_spec.rb +1 -1
  62. data/spec/unit/indirector/file_bucket_file/file_spec.rb +3 -3
  63. data/spec/unit/indirector/request_spec.rb +16 -1
  64. data/spec/unit/module_spec.rb +29 -0
  65. data/spec/unit/network/http/api/indirected_routes_spec.rb +3 -3
  66. data/spec/unit/network/http/rack/rest_spec.rb +3 -3
  67. data/spec/unit/type/file_spec.rb +46 -0
  68. data/spec/unit/util_spec.rb +230 -1
  69. data/tasks/parallel.rake +12 -7
  70. metadata +184 -194
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2e3344150cb64ddf6fd3ccfa7da942b6b993abff
4
+ data.tar.gz: ed957f24eef19e4e9bbe540d444b12cd2d2a5e16
5
+ SHA512:
6
+ metadata.gz: 5d49f0c0f6a79566f905a2d98080bf65e6857629d78c3aba8a8219573e420f00c933e57126c052aea8257e03094e39264028b34862321e5b4fd080bcdf9e7981
7
+ data.tar.gz: caaf06d2b18158bbc63fd41ed54b22620dda2996f73c2af0ea20765050db58c5036c3f0e9edd870b28a4fe0a206685946665da12105b6b98dece6c738a921dd8
@@ -243,7 +243,7 @@ Copyright (c) 2015 Puppet Inc., LLC Licensed under the Apache 2.0 License
243
243
  # raise "No node was given via the '--node' flag for the scope of the lookup.\n#{RUN_HELP}"
244
244
  #end
245
245
 
246
- if (options[:sort_merge_arrays] || options[:merge_hash_arrays] || options[:prefix]) && options[:merge] != 'deep'
246
+ if (options[:sort_merged_arrays] || options[:merge_hash_arrays] || options[:prefix]) && options[:merge] != 'deep'
247
247
  raise "The options #{DEEP_MERGE_OPTIONS} are only available with '--merge deep'\n#{RUN_HELP}"
248
248
  end
249
249
 
@@ -260,7 +260,7 @@ Copyright (c) 2015 Puppet Inc., LLC Licensed under the Apache 2.0 License
260
260
 
261
261
  if merge == 'deep'
262
262
  merge_options = {'strategy' => 'deep',
263
- 'sort_merge_arrays' => !options[:sort_merge_arrays].nil?,
263
+ 'sort_merged_arrays' => !options[:sort_merged_arrays].nil?,
264
264
  'merge_hash_arrays' => !options[:merge_hash_arrays].nil?}
265
265
 
266
266
  if options[:prefix]
@@ -32,6 +32,6 @@ module Puppet::Configurer::FactHandler
32
32
 
33
33
  text = facts.render(:pson)
34
34
 
35
- {:facts_format => :pson, :facts => CGI.escape(text)}
35
+ {:facts_format => :pson, :facts => Puppet::Util.uri_query_encode(text)}
36
36
  end
37
37
  end
@@ -316,34 +316,36 @@ Puppet::Face.define(:epp, '0.0.1') do
316
316
  options[:header] = options[:header].nil? ? true : options[:header]
317
317
 
318
318
  compiler = create_compiler(options)
319
-
320
- # Print to a buffer since the face needs to return the resulting string
321
- # and the face API is "all or nothing"
322
- #
323
- buffer = StringIO.new
324
- status = true
325
- if options[:e]
326
- buffer.print render_inline(options[:e], compiler, options)
327
- elsif args.empty?
328
- if ! STDIN.tty?
329
- buffer.print render_inline(STDIN.read, compiler, options)
319
+ compiler.with_context_overrides('For rendering epp') do
320
+
321
+ # Print to a buffer since the face needs to return the resulting string
322
+ # and the face API is "all or nothing"
323
+ #
324
+ buffer = StringIO.new
325
+ status = true
326
+ if options[:e]
327
+ buffer.print render_inline(options[:e], compiler, options)
328
+ elsif args.empty?
329
+ if ! STDIN.tty?
330
+ buffer.print render_inline(STDIN.read, compiler, options)
331
+ else
332
+ raise Puppet::Error, "No input to process given on command line or stdin"
333
+ end
330
334
  else
331
- raise Puppet::Error, "No input to process given on command line or stdin"
332
- end
333
- else
334
- show_filename = args.count > 1
335
- file_nbr = 0
336
- args.each do |file|
337
- begin
338
- buffer.print render_file(file, compiler, options, show_filename, file_nbr += 1)
339
- rescue Puppet::ParseError => detail
340
- Puppet.err(detail.message)
341
- status = false
335
+ show_filename = args.count > 1
336
+ file_nbr = 0
337
+ args.each do |file|
338
+ begin
339
+ buffer.print render_file(file, compiler, options, show_filename, file_nbr += 1)
340
+ rescue Puppet::ParseError => detail
341
+ Puppet.err(detail.message)
342
+ status = false
343
+ end
342
344
  end
343
345
  end
346
+ raise Puppet::Error, "error while rendering epp" unless status
347
+ buffer.string
344
348
  end
345
- raise Puppet::Error, "error while rendering epp" unless status
346
- buffer.string
347
349
  end
348
350
  end
349
351
 
@@ -31,14 +31,14 @@ class Puppet::FileServing::Metadata < Puppet::FileServing::Base
31
31
 
32
32
  def content_uri=(path)
33
33
  begin
34
- uri = URI.parse(URI.escape(path))
34
+ uri = URI.parse(Puppet::Util.uri_encode(path))
35
35
  rescue URI::InvalidURIError => detail
36
36
  raise(ArgumentError, "Could not understand URI #{path}: #{detail}")
37
37
  end
38
38
  raise(ArgumentError, "Cannot use opaque URLs '#{path}'") unless uri.hierarchical?
39
39
  raise(ArgumentError, "Must use URLs of type puppet as content URI") if uri.scheme != "puppet"
40
40
 
41
- @content_uri = path
41
+ @content_uri = path.encode(Encoding::UTF_8)
42
42
  end
43
43
 
44
44
  class MetaStat
@@ -53,12 +53,13 @@ class Puppet::Forge < SemanticPuppet::Dependency::Source
53
53
  # bad HTTP response
54
54
  def search(term)
55
55
  matches = []
56
- uri = "/v3/modules?query=#{URI.escape(term)}"
56
+ uri = "/v3/modules?query=#{term}"
57
57
  if Puppet[:module_groups]
58
- uri += "&module_groups=#{Puppet[:module_groups]}"
58
+ uri += "&module_groups=#{Puppet[:module_groups].gsub('+', ' ')}"
59
59
  end
60
60
 
61
61
  while uri
62
+ # make_http_request URI encodes parameters
62
63
  response = make_http_request(uri)
63
64
 
64
65
  if response.code == '200'
@@ -90,11 +91,12 @@ class Puppet::Forge < SemanticPuppet::Dependency::Source
90
91
  name = input.tr('/', '-')
91
92
  uri = "/v3/releases?module=#{name}"
92
93
  if Puppet[:module_groups]
93
- uri += "&module_groups=#{Puppet[:module_groups]}"
94
+ uri += "&module_groups=#{Puppet[:module_groups].gsub('+', ' ')}"
94
95
  end
95
96
  releases = []
96
97
 
97
98
  while uri
99
+ # make_http_request URI encodes parameters
98
100
  response = make_http_request(uri)
99
101
 
100
102
  if response.code == '200'
@@ -24,6 +24,7 @@ class Puppet::Forge
24
24
  uri = url.is_a?(::URI) ? url : ::URI.parse(url)
25
25
  unless cached_file.file?
26
26
  if uri.scheme == 'file'
27
+ # CGI.unescape butchers Uris that are escaped properly
27
28
  FileUtils.cp(URI.unescape(uri.path), cached_file)
28
29
  else
29
30
  # TODO: Handle HTTPS; probably should use repository.contact
@@ -57,6 +57,7 @@ class Puppet::Forge
57
57
  end
58
58
  end
59
59
 
60
+ # responsible for properly encoding a URI
60
61
  def get_request_object(path)
61
62
  headers = {
62
63
  "User-Agent" => user_agent,
@@ -72,7 +73,7 @@ class Puppet::Forge
72
73
  headers = headers.merge({"Authorization" => forge_authorization})
73
74
  end
74
75
 
75
- request = Net::HTTP::Get.new(URI.escape(path), headers)
76
+ request = Net::HTTP::Get.new(Puppet::Util.uri_encode(path), headers)
76
77
 
77
78
  unless @uri.user.nil? || @uri.password.nil? || forge_authorization
78
79
  request.basic_auth(@uri.user, @uri.password)
@@ -26,7 +26,7 @@ class Puppet::Resource::Catalog::Compiler < Puppet::Indirector::Code
26
26
  if text_facts.is_a?(Puppet::Node::Facts)
27
27
  facts = text_facts
28
28
  elsif format == 'pson'
29
- # We unescape here because the corresponding code in Puppet::Configurer::FactHandler escapes
29
+ # We unescape here because the corresponding code in Puppet::Configurer::FactHandler encodes with Puppet::Util.uri_query_encode
30
30
  facts = Puppet::Node::Facts.convert_from('pson', CGI.unescape(text_facts))
31
31
  else
32
32
  raise ArgumentError, "Unsupported facts format"
@@ -105,7 +105,7 @@ class Puppet::Resource::Catalog::Compiler < Puppet::Indirector::Code
105
105
  # This does that, while preserving any user-specified server or port.
106
106
  source_path = Pathname.new(metadata.full_path)
107
107
  path = source_path.relative_path_from(environment_path).to_s
108
- source_as_uri = URI.parse(URI.escape(source))
108
+ source_as_uri = URI.parse(Puppet::Util.uri_encode(source))
109
109
  server = source_as_uri.host
110
110
  port = ":#{source_as_uri.port}" if source_as_uri.port
111
111
  return "puppet://#{server}#{port}/#{path}"
@@ -130,7 +130,8 @@ class Puppet::Resource::Catalog::Compiler < Puppet::Indirector::Code
130
130
  # for the 'modules' mount and the resolved path is of the form:
131
131
  # $codedir/environments/$environment/*/*/files/**
132
132
  def inlineable_metadata?(metadata, source, environment_path)
133
- source_as_uri = URI.parse(URI.escape(source))
133
+ source_as_uri = URI.parse(Puppet::Util.uri_encode(source))
134
+
134
135
  location = Puppet::Module::FILETYPES['files']
135
136
 
136
137
  !!(source_as_uri.path =~ /^\/modules\// &&
@@ -41,8 +41,12 @@ class Puppet::Indirector::Request
41
41
  end
42
42
  end
43
43
 
44
+ # @api private
45
+ # @deprecated used only internally to be removed in Puppet 5
44
46
  def escaped_key
45
- URI.escape(key)
47
+ # Puppet::Network::HTTP::API::IndirectedRoutes is the only caller to escaped_key
48
+ # and these fragments only appear in the path part of a URI
49
+ Puppet::Util.uri_encode(key)
46
50
  end
47
51
 
48
52
  # LAK:NOTE This is a messy interface to the cache, and it's only
@@ -143,7 +147,7 @@ class Puppet::Indirector::Request
143
147
 
144
148
  def encode_params(params)
145
149
  params.collect do |key, value|
146
- "#{key}=#{CGI.escape(value.to_s)}"
150
+ "#{key}=#{Puppet::Util.uri_query_encode(value.to_s)}"
147
151
  end.join("&")
148
152
  end
149
153
 
@@ -243,9 +247,8 @@ class Puppet::Indirector::Request
243
247
  def set_uri_key(key)
244
248
  @uri = key
245
249
  begin
246
- # calling URI.escape for UTF-8 characters will % escape them
247
- # and the resulting string components of the URI are now ASCII
248
- uri = URI.parse(URI.escape(key))
250
+ # calling uri_encode for UTF-8 characters will % escape them and keep them UTF-8
251
+ uri = URI.parse(Puppet::Util.uri_encode(key))
249
252
  rescue => detail
250
253
  raise ArgumentError, "Could not understand URL #{key}: #{detail}", detail.backtrace
251
254
  end
@@ -274,8 +277,6 @@ class Puppet::Indirector::Request
274
277
  @protocol = uri.scheme
275
278
  end
276
279
 
277
- # The unescaped bytes are correct but in ASCII and must be treated
278
- # as UTF-8 for the sake of performing string comparisons later
279
- @key = URI.unescape(uri.path.sub(/^\//, '')).force_encoding(Encoding::UTF_8)
280
+ @key = URI.unescape(uri.path.sub(/^\//, ''))
280
281
  end
281
282
  end
@@ -68,6 +68,17 @@ class Puppet::Module
68
68
  load_metadata
69
69
 
70
70
  @absolute_path_to_manifests = Puppet::FileSystem::PathPattern.absolute(manifests)
71
+
72
+ # i18n initialization for modules
73
+ if Puppet::GETTEXT_AVAILABLE
74
+ begin
75
+ initialize_i18n
76
+ rescue Exception => e
77
+ Puppet.warning _("GettextSetup initialization for %{module_name} failed with: %{error_message}") % { module_name: name, error_message: e.message }
78
+ end
79
+ else
80
+ Puppet.warning _("GettextSetup is not available, skipping GettextSetup initialization for %{module_name}.") % { module_name: name }
81
+ end
71
82
  end
72
83
 
73
84
  # @deprecated The puppetversion module metadata field is no longer used.
@@ -353,8 +364,27 @@ class Puppet::Module
353
364
  self.environment == other.environment
354
365
  end
355
366
 
367
+ def initialize_i18n
368
+ module_name = @forge_name.gsub("/","-") if @forge_name
369
+ return if module_name.nil? || i18n_initialized?(module_name)
370
+
371
+ locales_path = File.absolute_path('locales', path)
372
+
373
+ begin
374
+ GettextSetup.initialize(locales_path)
375
+ Puppet.debug "#{module_name} initialized for i18n: #{GettextSetup.translation_repositories[module_name]}"
376
+ rescue
377
+ config_path = File.absolute_path('config.yaml', locales_path)
378
+ Puppet.debug "Could not find locales configuration file for #{module_name} at #{config_path}. Skipping i18n initialization."
379
+ end
380
+ end
381
+
356
382
  private
357
383
 
384
+ def i18n_initialized?(module_name)
385
+ GettextSetup.translation_repositories.has_key? module_name
386
+ end
387
+
358
388
  def wanted_manifests_from(pattern)
359
389
  begin
360
390
  extended = File.extname(pattern).empty? ? "#{pattern}.pp" : pattern
@@ -87,7 +87,8 @@ class Puppet::Network::HTTP::RackREST
87
87
  # in the indirector / HTTP layer which consumes this path, however, assumes
88
88
  # that it has already been unescaped, so it is unescaped here.
89
89
  if request.path
90
- URI.unescape(request.path)
90
+ # don't use CGI.unescape which mangles space handling
91
+ URI.unescape(request.path.encode(Encoding::UTF_8))
91
92
  end
92
93
  end
93
94
 
@@ -156,6 +156,10 @@ class Puppet::Parser::Compiler
156
156
  # Return a list of all of the defined classes.
157
157
  def_delegator :@catalog, :classes, :classlist
158
158
 
159
+ def with_context_overrides(description = '', &block)
160
+ Puppet.override( @context_overrides , description, &block)
161
+ end
162
+
159
163
  # Compiler our catalog. This mostly revolves around finding and evaluating classes.
160
164
  # This is the main entry into our catalog.
161
165
  def compile
@@ -56,5 +56,5 @@ For more information about data types, see the
56
56
  - Since 4.0.0
57
57
  DOC
58
58
  ) do |args|
59
- Error.is4x('assert_type')
59
+ Puppet::Parser::Functions::Error.is4x('assert_type')
60
60
  end
@@ -20,5 +20,5 @@ To search for the existence of files, use the `find_file()` function.
20
20
  - since 4.8.0
21
21
  DOC
22
22
  ) do |args|
23
- Error.is4x('binary_file')
23
+ Puppet::Parser::Functions::Error.is4x('binary_file')
24
24
  end
@@ -35,5 +35,5 @@ Would notice the value `[10]`
35
35
  * Since 4.8.0
36
36
  DOC
37
37
  ) do |args|
38
- Error.is4x('break')
38
+ Puppet::Parser::Functions::Error.is4x('break')
39
39
  end
@@ -103,5 +103,5 @@ defined('$tmp_file2')
103
103
  - Since 4.0.0 includes all future parser features
104
104
  DOC
105
105
  ) do |vals|
106
- Error.is4x('defined')
106
+ Puppet::Parser::Functions::Error.is4x('defined')
107
107
  end
@@ -25,5 +25,5 @@ Would notice the value 100.
25
25
  * Since 4.5.0
26
26
  DOC
27
27
  ) do |args|
28
- Error.is4x('dig')
28
+ Puppet::Parser::Functions::Error.is4x('dig')
29
29
  end
@@ -100,5 +100,5 @@ documentation.
100
100
  - Since 4.0.0
101
101
  DOC
102
102
  ) do |args|
103
- Error.is4x('each')
103
+ Puppet::Parser::Functions::Error.is4x('each')
104
104
  end
@@ -32,5 +32,5 @@ function fails to pass any required parameter.
32
32
 
33
33
  - Since 4.0.0") do |args|
34
34
 
35
- Error.is4x('epp')
35
+ Puppet::Parser::Functions::Error.is4x('epp')
36
36
  end
@@ -74,5 +74,5 @@ $filtered_data = $data.filter |$keys, $values| { $keys =~ /berry$/ and $values <
74
74
  - Since 4.0.0
75
75
  DOC
76
76
  ) do |args|
77
- Error.is4x('filter')
77
+ Puppet::Parser::Functions::Error.is4x('filter')
78
78
  end
@@ -23,6 +23,6 @@ The function returns `undef` if none of the given paths were found
23
23
  - since 4.8.0
24
24
  DOC
25
25
  ) do |args|
26
- Error.is4x('find_file')
26
+ Puppet::Parser::Functions::Error.is4x('find_file')
27
27
  end
28
28
 
@@ -47,5 +47,5 @@ END
47
47
  - Since 3.5
48
48
  - Requires [future parser](/puppet/3.8/reference/experiments_future.html) in Puppet 3.5 to 3.8") do |arguments|
49
49
 
50
- Error.is4x('inline_epp')
50
+ Puppet::Parser::Functions::Error.is4x('inline_epp')
51
51
  end
@@ -45,5 +45,5 @@ Would notice the value `20`
45
45
  * Since 4.5.0
46
46
  DOC
47
47
  ) do |args|
48
- Error.is4x('lest')
48
+ Puppet::Parser::Functions::Error.is4x('lest')
49
49
  end
@@ -72,5 +72,5 @@ $transformed_data = $data.map |$key,$value| { $value }
72
72
  - Since 4.0.0
73
73
  DOC
74
74
  ) do |args|
75
- Error.is4x('map')
75
+ Puppet::Parser::Functions::Error.is4x('map')
76
76
  end
@@ -39,5 +39,5 @@ $matches = ["abc123","def456"].match(/([a-z]+)([1-9]+)/)
39
39
  - Since 4.0.0
40
40
  DOC
41
41
  ) do |args|
42
- Error.is4x('match')
42
+ Puppet::Parser::Functions::Error.is4x('match')
43
43
  end
@@ -934,6 +934,6 @@ $b = binary_file('mymodule/mypicture.jpg')
934
934
 
935
935
  DOC
936
936
  ) do |args|
937
- Error.is4x('new')
937
+ Puppet::Parser::Functions::Error.is4x('new')
938
938
  end
939
939
 
@@ -34,5 +34,5 @@ Would notice the value `[10, 200, 30]`
34
34
  * Since 4.8.0
35
35
  DOC
36
36
  ) do |args|
37
- Error.is4x('next')
37
+ Puppet::Parser::Functions::Error.is4x('next')
38
38
  end
@@ -102,5 +102,5 @@ $combine = $data.reduce( [d, 4] ) |$memo, $value| {
102
102
  - Since 4.0.0
103
103
  DOC
104
104
  ) do |args|
105
- Error.is4x('reduce')
105
+ Puppet::Parser::Functions::Error.is4x('reduce')
106
106
  end
@@ -67,5 +67,5 @@ Note that the returned value is ignored if used in a class or user defined type.
67
67
  * Since 4.8.0
68
68
  DOC
69
69
  ) do |args|
70
- Error.is4x('return')
70
+ Puppet::Parser::Functions::Error.is4x('return')
71
71
  end