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,52 @@
1
+ module SafeYAML
2
+ class PsychResolver < Resolver
3
+ NODE_TYPES = {
4
+ Psych::Nodes::Document => :root,
5
+ Psych::Nodes::Mapping => :map,
6
+ Psych::Nodes::Sequence => :seq,
7
+ Psych::Nodes::Scalar => :scalar,
8
+ Psych::Nodes::Alias => :alias
9
+ }.freeze
10
+
11
+ def initialize(options={})
12
+ super
13
+ @aliased_nodes = {}
14
+ end
15
+
16
+ def resolve_root(root)
17
+ resolve_seq(root).first
18
+ end
19
+
20
+ def resolve_alias(node)
21
+ resolve_node(@aliased_nodes[node.anchor])
22
+ end
23
+
24
+ def native_resolve(node)
25
+ @visitor ||= SafeYAML::SafeToRubyVisitor.new(self)
26
+ @visitor.accept(node)
27
+ end
28
+
29
+ def get_node_type(node)
30
+ NODE_TYPES[node.class]
31
+ end
32
+
33
+ def get_node_tag(node)
34
+ node.tag
35
+ end
36
+
37
+ def get_node_value(node)
38
+ @aliased_nodes[node.anchor] = node if node.respond_to?(:anchor) && node.anchor
39
+
40
+ case get_node_type(node)
41
+ when :root, :map, :seq
42
+ node.children
43
+ when :scalar
44
+ node.value
45
+ end
46
+ end
47
+
48
+ def value_is_quoted?(node)
49
+ node.quoted
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,94 @@
1
+ module SafeYAML
2
+ class Resolver
3
+ def initialize(options)
4
+ @options = SafeYAML::OPTIONS.merge(options || {})
5
+ @whitelist = @options[:whitelisted_tags] || []
6
+ @initializers = @options[:custom_initializers] || {}
7
+ @raise_on_unknown_tag = @options[:raise_on_unknown_tag]
8
+ end
9
+
10
+ def resolve_node(node)
11
+ return node if !node
12
+ return self.native_resolve(node) if tag_is_whitelisted?(self.get_node_tag(node))
13
+
14
+ case self.get_node_type(node)
15
+ when :root
16
+ resolve_root(node)
17
+ when :map
18
+ resolve_map(node)
19
+ when :seq
20
+ resolve_seq(node)
21
+ when :scalar
22
+ resolve_scalar(node)
23
+ when :alias
24
+ resolve_alias(node)
25
+ else
26
+ raise "Don't know how to resolve this node: #{node.inspect}"
27
+ end
28
+ end
29
+
30
+ def resolve_map(node)
31
+ tag = get_and_check_node_tag(node)
32
+ hash = @initializers.include?(tag) ? @initializers[tag].call : {}
33
+ map = normalize_map(self.get_node_value(node))
34
+
35
+ # Take the "<<" key nodes first, as these are meant to approximate a form of inheritance.
36
+ inheritors = map.select { |key_node, value_node| resolve_node(key_node) == "<<" }
37
+ inheritors.each do |key_node, value_node|
38
+ merge_into_hash(hash, resolve_node(value_node))
39
+ end
40
+
41
+ # All that's left should be normal (non-"<<") nodes.
42
+ (map - inheritors).each do |key_node, value_node|
43
+ hash[resolve_node(key_node)] = resolve_node(value_node)
44
+ end
45
+
46
+ return hash
47
+ end
48
+
49
+ def resolve_seq(node)
50
+ seq = self.get_node_value(node)
51
+
52
+ tag = get_and_check_node_tag(node)
53
+ arr = @initializers.include?(tag) ? @initializers[tag].call : []
54
+
55
+ seq.inject(arr) { |array, node| array << resolve_node(node) }
56
+ end
57
+
58
+ def resolve_scalar(node)
59
+ Transform.to_proper_type(self.get_node_value(node), self.value_is_quoted?(node), get_and_check_node_tag(node), @options)
60
+ end
61
+
62
+ def get_and_check_node_tag(node)
63
+ tag = self.get_node_tag(node)
64
+ SafeYAML.tag_safety_check!(tag, @options)
65
+ tag
66
+ end
67
+
68
+ def tag_is_whitelisted?(tag)
69
+ @whitelist.include?(tag)
70
+ end
71
+
72
+ def options
73
+ @options
74
+ end
75
+
76
+ private
77
+ def normalize_map(map)
78
+ # Syck creates Hashes from maps.
79
+ if map.is_a?(Hash)
80
+ map.inject([]) { |arr, key_and_value| arr << key_and_value }
81
+
82
+ # Psych is really weird; it flattens out a Hash completely into: [key, value, key, value, ...]
83
+ else
84
+ map.each_slice(2).to_a
85
+ end
86
+ end
87
+
88
+ def merge_into_hash(hash, array)
89
+ array.each do |key, value|
90
+ hash[key] = value
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,17 @@
1
+ module SafeYAML
2
+ class SafeToRubyVisitor < Psych::Visitors::ToRuby
3
+ def initialize(resolver)
4
+ super()
5
+ @resolver = resolver
6
+ end
7
+
8
+ def accept(node)
9
+ if node.tag
10
+ SafeYAML.tag_safety_check!(node.tag, @resolver.options)
11
+ return super
12
+ end
13
+
14
+ @resolver.resolve_node(node)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ # Hack to JRuby 1.8's YAML Parser Yecht
2
+ #
3
+ # This file is always loaded AFTER either syck or psych are already
4
+ # loaded. It then looks at what constants are available and creates
5
+ # a consistent view on all rubys.
6
+ #
7
+ # Taken from rubygems and modified.
8
+ # See https://github.com/rubygems/rubygems/blob/master/lib/rubygems/syck_hack.rb
9
+
10
+ module YAML
11
+ # In newer 1.9.2, there is a Syck toplevel constant instead of it
12
+ # being underneith YAML. If so, reference it back under YAML as
13
+ # well.
14
+ if defined? ::Syck
15
+ # for tests that change YAML::ENGINE
16
+ # 1.8 does not support the second argument to const_defined?
17
+ remove_const :Syck rescue nil
18
+
19
+ Syck = ::Syck
20
+
21
+ # JRuby's "Syck" is called "Yecht"
22
+ elsif defined? YAML::Yecht
23
+ Syck = YAML::Yecht
24
+ end
25
+ end
26
+
27
+ # Sometime in the 1.9 dev cycle, the Syck constant was moved from under YAML
28
+ # to be a toplevel constant. So gemspecs created under these versions of Syck
29
+ # will have references to Syck::DefaultKey.
30
+ #
31
+ # So we need to be sure that we reference Syck at the toplevel too so that
32
+ # we can always load these kind of gemspecs.
33
+ #
34
+ if !defined?(Syck)
35
+ Syck = YAML::Syck
36
+ end
@@ -0,0 +1,43 @@
1
+ # This is, admittedly, pretty insane. Fundamentally the challenge here is this: if we want to allow
2
+ # whitelisting of tags (while still leveraging Syck's internal functionality), then we have to
3
+ # change how Syck::Node#transform works. But since we (SafeYAML) do not control instantiation of
4
+ # Syck::Node objects, we cannot, for example, subclass Syck::Node and override #tranform the "easy"
5
+ # way. So the only choice is to monkeypatch, like this. And the only way to make this work
6
+ # recursively with potentially call-specific options (that my feeble brain can think of) is to set
7
+ # pseudo-global options on the first call and unset them once the recursive stack has fully unwound.
8
+
9
+ monkeypatch = <<-EORUBY
10
+ class Node
11
+ @@safe_transform_depth = 0
12
+ @@safe_transform_whitelist = nil
13
+
14
+ def safe_transform(options={})
15
+ begin
16
+ @@safe_transform_depth += 1
17
+ @@safe_transform_whitelist ||= options[:whitelisted_tags]
18
+
19
+ if self.type_id
20
+ SafeYAML.tag_safety_check!(self.type_id, options)
21
+ return unsafe_transform if @@safe_transform_whitelist.include?(self.type_id)
22
+ end
23
+
24
+ SafeYAML::SyckResolver.new.resolve_node(self)
25
+
26
+ ensure
27
+ @@safe_transform_depth -= 1
28
+ if @@safe_transform_depth == 0
29
+ @@safe_transform_whitelist = nil
30
+ end
31
+ end
32
+ end
33
+
34
+ alias_method :unsafe_transform, :transform
35
+ alias_method :transform, :safe_transform
36
+ end
37
+ EORUBY
38
+
39
+ if defined?(YAML::Syck::Node)
40
+ YAML::Syck.module_eval monkeypatch
41
+ else
42
+ Syck.module_eval monkeypatch
43
+ end
@@ -0,0 +1,38 @@
1
+ module SafeYAML
2
+ class SyckResolver < Resolver
3
+ QUOTE_STYLES = [
4
+ :quote1,
5
+ :quote2
6
+ ].freeze
7
+
8
+ NODE_TYPES = {
9
+ Hash => :map,
10
+ Array => :seq,
11
+ String => :scalar
12
+ }.freeze
13
+
14
+ def initialize(options={})
15
+ super
16
+ end
17
+
18
+ def native_resolve(node)
19
+ node.transform(self.options)
20
+ end
21
+
22
+ def get_node_type(node)
23
+ NODE_TYPES[node.value.class]
24
+ end
25
+
26
+ def get_node_tag(node)
27
+ node.type_id
28
+ end
29
+
30
+ def get_node_value(node)
31
+ node.value
32
+ end
33
+
34
+ def value_is_quoted?(node)
35
+ QUOTE_STYLES.include?(node.instance_variable_get(:@style))
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,41 @@
1
+ require 'base64'
2
+
3
+ module SafeYAML
4
+ class Transform
5
+ TRANSFORMERS = [
6
+ Transform::ToSymbol.new,
7
+ Transform::ToInteger.new,
8
+ Transform::ToFloat.new,
9
+ Transform::ToNil.new,
10
+ Transform::ToBoolean.new,
11
+ Transform::ToDate.new
12
+ ]
13
+
14
+ def self.to_guessed_type(value, quoted=false, options=nil)
15
+ return value if quoted
16
+
17
+ if value.is_a?(String)
18
+ TRANSFORMERS.each do |transformer|
19
+ success, transformed_value = transformer.method(:transform?).arity == 1 ?
20
+ transformer.transform?(value) :
21
+ transformer.transform?(value, options)
22
+
23
+ return transformed_value if success
24
+ end
25
+ end
26
+
27
+ value
28
+ end
29
+
30
+ def self.to_proper_type(value, quoted=false, tag=nil, options=nil)
31
+ case tag
32
+ when "tag:yaml.org,2002:binary", "x-private:binary", "!binary"
33
+ decoded = Base64.decode64(value)
34
+ decoded = decoded.force_encoding(value.encoding) if decoded.respond_to?(:force_encoding)
35
+ decoded
36
+ else
37
+ self.to_guessed_type(value, quoted, options)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,21 @@
1
+ module SafeYAML
2
+ class Transform
3
+ class ToBoolean
4
+ include TransformationMap
5
+
6
+ set_predefined_values({
7
+ "yes" => true,
8
+ "on" => true,
9
+ "true" => true,
10
+ "no" => false,
11
+ "off" => false,
12
+ "false" => false
13
+ })
14
+
15
+ def transform?(value)
16
+ return false if value.length > 5
17
+ return PREDEFINED_VALUES.include?(value), PREDEFINED_VALUES[value]
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ module SafeYAML
2
+ class Transform
3
+ class ToDate
4
+ def transform?(value)
5
+ return true, Date.parse(value) if Parse::Date::DATE_MATCHER.match(value)
6
+ return true, Parse::Date.value(value) if Parse::Date::TIME_MATCHER.match(value)
7
+ false
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,33 @@
1
+ module SafeYAML
2
+ class Transform
3
+ class ToFloat
4
+ Infinity = 1.0 / 0.0
5
+ NaN = 0.0 / 0.0
6
+
7
+ PREDEFINED_VALUES = {
8
+ ".inf" => Infinity,
9
+ ".Inf" => Infinity,
10
+ ".INF" => Infinity,
11
+ "-.inf" => -Infinity,
12
+ "-.Inf" => -Infinity,
13
+ "-.INF" => -Infinity,
14
+ ".nan" => NaN,
15
+ ".NaN" => NaN,
16
+ ".NAN" => NaN,
17
+ }.freeze
18
+
19
+ MATCHER = /\A[-+]?(?:\d[\d_]*)?\.[\d_]+(?:[eE][-+][\d]+)?\Z/.freeze
20
+
21
+ def transform?(value)
22
+ return true, Float(value) if MATCHER.match(value)
23
+ try_edge_cases?(value)
24
+ end
25
+
26
+ def try_edge_cases?(value)
27
+ return true, PREDEFINED_VALUES[value] if PREDEFINED_VALUES.include?(value)
28
+ return true, Parse::Sexagesimal.value(value) if Parse::Sexagesimal::FLOAT_MATCHER.match(value)
29
+ return false
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ module SafeYAML
2
+ class Transform
3
+ class ToInteger
4
+ MATCHERS = Deep.freeze([
5
+ /\A[-+]?(0|([1-9][0-9_,]*))\Z/, # decimal
6
+ /\A0[0-7]+\Z/, # octal
7
+ /\A0x[0-9a-f]+\Z/i, # hexadecimal
8
+ /\A0b[01_]+\Z/ # binary
9
+ ])
10
+
11
+ def transform?(value)
12
+ MATCHERS.each do |matcher|
13
+ return true, Integer(value.gsub(",", "")) if matcher.match(value)
14
+ end
15
+ try_edge_cases?(value)
16
+ end
17
+
18
+ def try_edge_cases?(value)
19
+ return true, Parse::Hexadecimal.value(value) if Parse::Hexadecimal::MATCHER.match(value)
20
+ return true, Parse::Sexagesimal.value(value) if Parse::Sexagesimal::INTEGER_MATCHER.match(value)
21
+ return false
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ module SafeYAML
2
+ class Transform
3
+ class ToNil
4
+ include TransformationMap
5
+
6
+ set_predefined_values({
7
+ "" => nil,
8
+ "~" => nil,
9
+ "null" => nil,
10
+ })
11
+
12
+ def transform?(value)
13
+ return false if value.length > 4
14
+ return PREDEFINED_VALUES.include?(value), PREDEFINED_VALUES[value]
15
+ end
16
+ end
17
+ end
18
+ end