puppet 3.2.1 → 3.2.2

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 (78) hide show
  1. data/install.rb +1 -1
  2. data/lib/puppet.rb +11 -0
  3. data/lib/puppet/indirector/report/processor.rb +1 -1
  4. data/lib/puppet/indirector/report/rest.rb +7 -0
  5. data/lib/puppet/indirector/resource/rest.rb +8 -0
  6. data/lib/puppet/indirector/rest.rb +80 -52
  7. data/lib/puppet/indirector/run/rest.rb +6 -0
  8. data/lib/puppet/network/formats.rb +20 -10
  9. data/lib/puppet/network/http/handler.rb +1 -1
  10. data/lib/puppet/node.rb +1 -1
  11. data/lib/puppet/node/facts.rb +23 -4
  12. data/lib/puppet/resource.rb +2 -4
  13. data/lib/puppet/resource/status.rb +28 -0
  14. data/lib/puppet/run.rb +24 -2
  15. data/lib/puppet/status.rb +6 -2
  16. data/lib/puppet/transaction/event.rb +19 -0
  17. data/lib/puppet/transaction/report.rb +40 -0
  18. data/lib/puppet/util/log.rb +19 -0
  19. data/lib/puppet/util/metric.rb +6 -0
  20. data/lib/puppet/util/monkey_patches.rb +0 -15
  21. data/lib/puppet/vendor.rb +55 -0
  22. data/lib/puppet/vendor/load_safe_yaml.rb +1 -0
  23. data/lib/puppet/vendor/require_vendored.rb +5 -0
  24. data/lib/puppet/vendor/safe_yaml/CHANGES.md +104 -0
  25. data/lib/puppet/vendor/safe_yaml/Gemfile +11 -0
  26. data/lib/puppet/vendor/safe_yaml/LICENSE.txt +22 -0
  27. data/lib/puppet/vendor/safe_yaml/README.md +179 -0
  28. data/lib/puppet/vendor/safe_yaml/Rakefile +6 -0
  29. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml.rb +253 -0
  30. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/deep.rb +34 -0
  31. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/parse/date.rb +27 -0
  32. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/parse/hexadecimal.rb +12 -0
  33. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/parse/sexagesimal.rb +26 -0
  34. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/psych_handler.rb +92 -0
  35. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/psych_resolver.rb +52 -0
  36. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/resolver.rb +94 -0
  37. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/safe_to_ruby_visitor.rb +17 -0
  38. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/syck_hack.rb +36 -0
  39. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/syck_node_monkeypatch.rb +43 -0
  40. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/syck_resolver.rb +38 -0
  41. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/transform.rb +41 -0
  42. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/transform/to_boolean.rb +21 -0
  43. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/transform/to_date.rb +11 -0
  44. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/transform/to_float.rb +33 -0
  45. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/transform/to_integer.rb +25 -0
  46. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/transform/to_nil.rb +18 -0
  47. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/transform/to_symbol.rb +13 -0
  48. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/transform/transformation_map.rb +47 -0
  49. data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/version.rb +3 -0
  50. data/lib/puppet/vendor/safe_yaml/run_specs_all_ruby_versions.sh +21 -0
  51. data/lib/puppet/vendor/safe_yaml/safe_yaml.gemspec +18 -0
  52. data/lib/puppet/vendor/safe_yaml/spec/exploit.1.9.2.yaml +2 -0
  53. data/lib/puppet/vendor/safe_yaml/spec/exploit.1.9.3.yaml +2 -0
  54. data/lib/puppet/vendor/safe_yaml/spec/psych_resolver_spec.rb +10 -0
  55. data/lib/puppet/vendor/safe_yaml/spec/resolver_specs.rb +250 -0
  56. data/lib/puppet/vendor/safe_yaml/spec/safe_yaml_spec.rb +702 -0
  57. data/lib/puppet/vendor/safe_yaml/spec/spec_helper.rb +18 -0
  58. data/lib/puppet/vendor/safe_yaml/spec/support/exploitable_back_door.rb +29 -0
  59. data/lib/puppet/vendor/safe_yaml/spec/syck_resolver_spec.rb +10 -0
  60. data/lib/puppet/vendor/safe_yaml/spec/transform/base64_spec.rb +11 -0
  61. data/lib/puppet/vendor/safe_yaml/spec/transform/to_date_spec.rb +34 -0
  62. data/lib/puppet/vendor/safe_yaml/spec/transform/to_float_spec.rb +42 -0
  63. data/lib/puppet/vendor/safe_yaml/spec/transform/to_integer_spec.rb +59 -0
  64. data/lib/puppet/vendor/safe_yaml/spec/transform/to_symbol_spec.rb +49 -0
  65. data/lib/puppet/vendor/safe_yaml_patches.rb +9 -0
  66. data/lib/puppet/version.rb +1 -1
  67. data/spec/lib/puppet_spec/matchers.rb +8 -0
  68. data/spec/unit/application/facts_spec.rb +1 -0
  69. data/spec/unit/file_serving/metadata_spec.rb +20 -28
  70. data/spec/unit/indirector/report/rest_spec.rb +41 -0
  71. data/spec/unit/indirector/rest_spec.rb +307 -334
  72. data/spec/unit/network/formats_spec.rb +36 -27
  73. data/spec/unit/network/http/handler_spec.rb +3 -12
  74. data/spec/unit/node_spec.rb +14 -0
  75. data/spec/unit/resource_spec.rb +5 -35
  76. data/spec/unit/run_spec.rb +25 -6
  77. data/spec/unit/status_spec.rb +6 -0
  78. metadata +2566 -2521
@@ -0,0 +1,6 @@
1
+ require "rspec/core/rake_task"
2
+
3
+ desc "Run specs"
4
+ RSpec::Core::RakeTask.new(:spec) do |t|
5
+ t.rspec_opts = %w(--color)
6
+ end
@@ -0,0 +1,253 @@
1
+ require "yaml"
2
+
3
+ # This needs to be defined up front in case any internal classes need to base
4
+ # their behavior off of this.
5
+ module SafeYAML
6
+ YAML_ENGINE = defined?(YAML::ENGINE) ? YAML::ENGINE.yamler : "syck"
7
+ end
8
+
9
+ require "set"
10
+ require "safe_yaml/deep"
11
+ require "safe_yaml/parse/hexadecimal"
12
+ require "safe_yaml/parse/sexagesimal"
13
+ require "safe_yaml/parse/date"
14
+ require "safe_yaml/transform/transformation_map"
15
+ require "safe_yaml/transform/to_boolean"
16
+ require "safe_yaml/transform/to_date"
17
+ require "safe_yaml/transform/to_float"
18
+ require "safe_yaml/transform/to_integer"
19
+ require "safe_yaml/transform/to_nil"
20
+ require "safe_yaml/transform/to_symbol"
21
+ require "safe_yaml/transform"
22
+ require "safe_yaml/resolver"
23
+ require "safe_yaml/syck_hack" if defined?(JRUBY_VERSION)
24
+
25
+ module SafeYAML
26
+ MULTI_ARGUMENT_YAML_LOAD = YAML.method(:load).arity != 1
27
+
28
+ DEFAULT_OPTIONS = Deep.freeze({
29
+ :default_mode => nil,
30
+ :suppress_warnings => false,
31
+ :deserialize_symbols => false,
32
+ :whitelisted_tags => [],
33
+ :custom_initializers => {},
34
+ :raise_on_unknown_tag => false
35
+ })
36
+
37
+ OPTIONS = Deep.copy(DEFAULT_OPTIONS)
38
+
39
+ module_function
40
+ def restore_defaults!
41
+ OPTIONS.clear.merge!(Deep.copy(DEFAULT_OPTIONS))
42
+ end
43
+
44
+ def tag_safety_check!(tag, options)
45
+ return if tag.nil? || tag == "!"
46
+ if options[:raise_on_unknown_tag] && !options[:whitelisted_tags].include?(tag) && !tag_is_explicitly_trusted?(tag)
47
+ raise "Unknown YAML tag '#{tag}'"
48
+ end
49
+ end
50
+
51
+ def whitelist!(*classes)
52
+ classes.each do |klass|
53
+ whitelist_class!(klass)
54
+ end
55
+ end
56
+
57
+ def whitelist_class!(klass)
58
+ raise "#{klass} not a Class" unless klass.is_a?(::Class)
59
+
60
+ klass_name = klass.name
61
+ raise "#{klass} cannot be anonymous" if klass_name.nil? || klass_name.empty?
62
+
63
+ # Whitelist any built-in YAML tags supplied by Syck or Psych.
64
+ predefined_tag = predefined_tags[klass]
65
+ if predefined_tag
66
+ OPTIONS[:whitelisted_tags] << predefined_tag
67
+ return
68
+ end
69
+
70
+ # Exception is exceptional (har har).
71
+ tag_class = klass < Exception ? "exception" : "object"
72
+
73
+ tag_prefix = case YAML_ENGINE
74
+ when "psych" then "!ruby/#{tag_class}"
75
+ when "syck" then "tag:ruby.yaml.org,2002:#{tag_class}"
76
+ else raise "unknown YAML_ENGINE #{YAML_ENGINE}"
77
+ end
78
+ OPTIONS[:whitelisted_tags] << "#{tag_prefix}:#{klass_name}"
79
+ end
80
+
81
+ def predefined_tags
82
+ if @predefined_tags.nil?
83
+ @predefined_tags = {}
84
+
85
+ if YAML_ENGINE == "syck"
86
+ YAML.tagged_classes.each do |tag, klass|
87
+ @predefined_tags[klass] = tag
88
+ end
89
+
90
+ else
91
+ # Special tags appear to be hard-coded in Psych:
92
+ # https://github.com/tenderlove/psych/blob/v1.3.4/lib/psych/visitors/to_ruby.rb
93
+ # Fortunately, there aren't many that SafeYAML doesn't already support.
94
+ @predefined_tags.merge!({
95
+ Exception => "!ruby/exception",
96
+ Range => "!ruby/range",
97
+ Regexp => "!ruby/regexp",
98
+ })
99
+ end
100
+ end
101
+
102
+ @predefined_tags
103
+ end
104
+
105
+ if YAML_ENGINE == "psych"
106
+ def tag_is_explicitly_trusted?(tag)
107
+ false
108
+ end
109
+
110
+ else
111
+ TRUSTED_TAGS = Set.new([
112
+ "tag:yaml.org,2002:binary",
113
+ "tag:yaml.org,2002:bool#no",
114
+ "tag:yaml.org,2002:bool#yes",
115
+ "tag:yaml.org,2002:float",
116
+ "tag:yaml.org,2002:float#fix",
117
+ "tag:yaml.org,2002:int",
118
+ "tag:yaml.org,2002:map",
119
+ "tag:yaml.org,2002:null",
120
+ "tag:yaml.org,2002:seq",
121
+ "tag:yaml.org,2002:str",
122
+ "tag:yaml.org,2002:timestamp",
123
+ "tag:yaml.org,2002:timestamp#ymd"
124
+ ]).freeze
125
+
126
+ def tag_is_explicitly_trusted?(tag)
127
+ TRUSTED_TAGS.include?(tag)
128
+ end
129
+ end
130
+ end
131
+
132
+ module YAML
133
+ def self.load_with_options(yaml, *original_arguments)
134
+ filename, options = filename_and_options_from_arguments(original_arguments)
135
+ safe_mode = safe_mode_from_options("load", options)
136
+ arguments = [yaml]
137
+
138
+ if safe_mode == :safe
139
+ arguments << filename if SafeYAML::YAML_ENGINE == "psych"
140
+ arguments << options_for_safe_load(options)
141
+ safe_load(*arguments)
142
+ else
143
+ arguments << filename if SafeYAML::MULTI_ARGUMENT_YAML_LOAD
144
+ unsafe_load(*arguments)
145
+ end
146
+ end
147
+
148
+ def self.load_file_with_options(file, options={})
149
+ safe_mode = safe_mode_from_options("load_file", options)
150
+ if safe_mode == :safe
151
+ safe_load_file(file, options_for_safe_load(options))
152
+ else
153
+ unsafe_load_file(file)
154
+ end
155
+ end
156
+
157
+ if SafeYAML::YAML_ENGINE == "psych"
158
+ require "safe_yaml/psych_handler"
159
+ require "safe_yaml/psych_resolver"
160
+ require "safe_yaml/safe_to_ruby_visitor"
161
+
162
+ def self.safe_load(yaml, filename=nil, options={})
163
+ # If the user hasn't whitelisted any tags, we can go with this implementation which is
164
+ # significantly faster.
165
+ if (options && options[:whitelisted_tags] || SafeYAML::OPTIONS[:whitelisted_tags]).empty?
166
+ safe_handler = SafeYAML::PsychHandler.new(options)
167
+ arguments_for_parse = [yaml]
168
+ arguments_for_parse << filename if SafeYAML::MULTI_ARGUMENT_YAML_LOAD
169
+ Psych::Parser.new(safe_handler).parse(*arguments_for_parse)
170
+ return safe_handler.result || false
171
+
172
+ else
173
+ safe_resolver = SafeYAML::PsychResolver.new(options)
174
+ tree = SafeYAML::MULTI_ARGUMENT_YAML_LOAD ?
175
+ Psych.parse(yaml, filename) :
176
+ Psych.parse(yaml)
177
+ return safe_resolver.resolve_node(tree)
178
+ end
179
+ end
180
+
181
+ def self.safe_load_file(filename, options={})
182
+ File.open(filename, 'r:bom|utf-8') { |f| self.safe_load(f, filename, options) }
183
+ end
184
+
185
+ def self.unsafe_load_file(filename)
186
+ if SafeYAML::MULTI_ARGUMENT_YAML_LOAD
187
+ # https://github.com/tenderlove/psych/blob/v1.3.2/lib/psych.rb#L296-298
188
+ File.open(filename, 'r:bom|utf-8') { |f| self.unsafe_load(f, filename) }
189
+ else
190
+ # https://github.com/tenderlove/psych/blob/v1.2.2/lib/psych.rb#L231-233
191
+ self.unsafe_load File.open(filename)
192
+ end
193
+ end
194
+
195
+ else
196
+ require "safe_yaml/syck_resolver"
197
+ require "safe_yaml/syck_node_monkeypatch"
198
+
199
+ def self.safe_load(yaml, options={})
200
+ resolver = SafeYAML::SyckResolver.new(SafeYAML::OPTIONS.merge(options || {}))
201
+ tree = YAML.parse(yaml)
202
+ return resolver.resolve_node(tree)
203
+ end
204
+
205
+ def self.safe_load_file(filename, options={})
206
+ File.open(filename) { |f| self.safe_load(f, options) }
207
+ end
208
+
209
+ def self.unsafe_load_file(filename)
210
+ # https://github.com/indeyets/syck/blob/master/ext/ruby/lib/yaml.rb#L133-135
211
+ File.open(filename) { |f| self.unsafe_load(f) }
212
+ end
213
+ end
214
+
215
+ class << self
216
+ alias_method :unsafe_load, :load
217
+ alias_method :load, :load_with_options
218
+ alias_method :load_file, :load_file_with_options
219
+
220
+ private
221
+ def filename_and_options_from_arguments(arguments)
222
+ if arguments.count == 1
223
+ if arguments.first.is_a?(String)
224
+ return arguments.first, {}
225
+ else
226
+ return nil, arguments.first || {}
227
+ end
228
+
229
+ else
230
+ return arguments.first, arguments.last || {}
231
+ end
232
+ end
233
+
234
+ def safe_mode_from_options(method, options={})
235
+ if options[:safe].nil?
236
+ safe_mode = SafeYAML::OPTIONS[:default_mode] || :safe
237
+ if SafeYAML::OPTIONS[:default_mode].nil? && !SafeYAML::OPTIONS[:suppress_warnings]
238
+ Kernel.warn "Called '#{method}' without the :safe option -- defaulting to #{safe_mode} mode."
239
+ SafeYAML::OPTIONS[:suppress_warnings] = true
240
+ end
241
+ return safe_mode
242
+ end
243
+
244
+ options[:safe] ? :safe : :unsafe
245
+ end
246
+
247
+ def options_for_safe_load(base_options)
248
+ options = base_options.dup
249
+ options.delete(:safe)
250
+ options
251
+ end
252
+ end
253
+ end
@@ -0,0 +1,34 @@
1
+ module SafeYAML
2
+ class Deep
3
+ def self.freeze(object)
4
+ object.each do |*entry|
5
+ value = entry.last
6
+ case value
7
+ when String, Regexp
8
+ value.freeze
9
+ when Enumerable
10
+ Deep.freeze(value)
11
+ end
12
+ end
13
+
14
+ return object.freeze
15
+ end
16
+
17
+ def self.copy(object)
18
+ duplicate = object.dup rescue object
19
+
20
+ case object
21
+ when Array
22
+ (0...duplicate.count).each do |i|
23
+ duplicate[i] = Deep.copy(duplicate[i])
24
+ end
25
+ when Hash
26
+ duplicate.keys.each do |key|
27
+ duplicate[key] = Deep.copy(duplicate[key])
28
+ end
29
+ end
30
+
31
+ duplicate
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,27 @@
1
+ module SafeYAML
2
+ class Parse
3
+ class Date
4
+ # This one's easy enough :)
5
+ DATE_MATCHER = /\A(\d{4})-(\d{2})-(\d{2})\Z/.freeze
6
+
7
+ # This unbelievable little gem is taken basically straight from the YAML spec, but made
8
+ # slightly more readable (to my poor eyes at least) to me:
9
+ # http://yaml.org/type/timestamp.html
10
+ TIME_MATCHER = /\A\d{4}-\d{1,2}-\d{1,2}(?:[Tt]|\s+)\d{1,2}:\d{2}:\d{2}(?:\.\d*)?\s*(?:Z|[-+]\d{1,2}(?::?\d{2})?)?\Z/.freeze
11
+
12
+ SECONDS_PER_DAY = 60 * 60 * 24
13
+ MICROSECONDS_PER_SECOND = 1000000
14
+
15
+ # So this is weird. In Ruby 1.8.7, the DateTime#sec_fraction method returned fractional
16
+ # seconds in units of DAYS for some reason. In 1.9.2, they changed the units -- much more
17
+ # reasonably -- to seconds.
18
+ SEC_FRACTION_MULTIPLIER = RUBY_VERSION == "1.8.7" ? (SECONDS_PER_DAY * MICROSECONDS_PER_SECOND) : MICROSECONDS_PER_SECOND
19
+
20
+ def self.value(value)
21
+ d = DateTime.parse(value)
22
+ usec = d.sec_fraction * SEC_FRACTION_MULTIPLIER
23
+ Time.utc(d.year, d.month, d.day, d.hour, d.min, d.sec, usec) - (d.offset * SECONDS_PER_DAY)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,12 @@
1
+ module SafeYAML
2
+ class Parse
3
+ class Hexadecimal
4
+ MATCHER = /\A[-+]?0x[0-9a-fA-F_]+\Z/.freeze
5
+
6
+ def self.value(value)
7
+ # This is safe to do since we already validated the value.
8
+ return Integer(value.gsub(/_/, ""))
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,26 @@
1
+ module SafeYAML
2
+ class Parse
3
+ class Sexagesimal
4
+ INTEGER_MATCHER = /\A[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\Z/.freeze
5
+ FLOAT_MATCHER = /\A[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\.[0-9_]*\Z/.freeze
6
+
7
+ def self.value(value)
8
+ before_decimal, after_decimal = value.split(".")
9
+
10
+ whole_part = 0
11
+ multiplier = 1
12
+
13
+ before_decimal = before_decimal.split(":")
14
+ until before_decimal.empty?
15
+ whole_part += (Float(before_decimal.pop) * multiplier)
16
+ multiplier *= 60
17
+ end
18
+
19
+ result = whole_part
20
+ result += Float("." + after_decimal) unless after_decimal.nil?
21
+ result *= -1 if value[0] == "-"
22
+ result
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,92 @@
1
+ require "psych"
2
+ require "base64"
3
+
4
+ module SafeYAML
5
+ class PsychHandler < Psych::Handler
6
+ def initialize(options)
7
+ @options = SafeYAML::OPTIONS.merge(options || {})
8
+ @initializers = @options[:custom_initializers] || {}
9
+ @anchors = {}
10
+ @stack = []
11
+ @current_key = nil
12
+ @result = nil
13
+ end
14
+
15
+ def result
16
+ @result
17
+ end
18
+
19
+ def add_to_current_structure(value, anchor=nil, quoted=nil, tag=nil)
20
+ value = Transform.to_proper_type(value, quoted, tag, @options)
21
+
22
+ @anchors[anchor] = value if anchor
23
+
24
+ if @result.nil?
25
+ @result = value
26
+ @current_structure = @result
27
+ return
28
+ end
29
+
30
+ if @current_structure.respond_to?(:<<)
31
+ @current_structure << value
32
+
33
+ elsif @current_structure.respond_to?(:[]=)
34
+ if @current_key.nil?
35
+ @current_key = value
36
+
37
+ else
38
+ if @current_key == "<<"
39
+ @current_structure.merge!(value)
40
+ else
41
+ @current_structure[@current_key] = value
42
+ end
43
+
44
+ @current_key = nil
45
+ end
46
+
47
+ else
48
+ raise "Don't know how to add to a #{@current_structure.class}!"
49
+ end
50
+ end
51
+
52
+ def end_current_structure
53
+ @stack.pop
54
+ @current_structure = @stack.last
55
+ end
56
+
57
+ def streaming?
58
+ false
59
+ end
60
+
61
+ # event handlers
62
+ def alias(anchor)
63
+ add_to_current_structure(@anchors[anchor])
64
+ end
65
+
66
+ def scalar(value, anchor, tag, plain, quoted, style)
67
+ add_to_current_structure(value, anchor, quoted, tag)
68
+ end
69
+
70
+ def start_mapping(anchor, tag, implicit, style)
71
+ map = @initializers.include?(tag) ? @initializers[tag].call : {}
72
+ self.add_to_current_structure(map, anchor)
73
+ @current_structure = map
74
+ @stack.push(map)
75
+ end
76
+
77
+ def end_mapping
78
+ self.end_current_structure()
79
+ end
80
+
81
+ def start_sequence(anchor, tag, implicit, style)
82
+ seq = @initializers.include?(tag) ? @initializers[tag].call : []
83
+ self.add_to_current_structure(seq, anchor)
84
+ @current_structure = seq
85
+ @stack.push(seq)
86
+ end
87
+
88
+ def end_sequence
89
+ self.end_current_structure()
90
+ end
91
+ end
92
+ end