chef-attribute-validator 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NTZkNWQ0OWFiOTIwYmRlOWQ1ZWE3MTE5YzNhZjRmYzkzNDkxMTljZg==
4
+ MGNhOTQ2Yzg2ZmNjODk4M2I3ZjAzM2U2YjAzNTgxMTExYmY0MGY0YQ==
5
5
  data.tar.gz: !binary |-
6
- ZjczMmQzYmNjNDJiNDM1MzM1MTJhNDJlNDA3MTIwYmQxMWY0ODVjNQ==
6
+ MmRkZmM4Y2NmYWJhNzNmMzM2OGU1Mzc4MTU3M2ZkOTMzMGEwNDc3Yg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZWM2OTNlM2NjYmVkMDM0ZTI4MjdmZTYxNjk5YzA1Y2U0MWFmZmViYTM5MzQ4
10
- MjgyZDNmM2UzODdhODRhODNjYjMxYTZhOGJkODVlNmI2YjQ1YjYxMTRiZDUw
11
- ZDJjZDZlOWIxODlmZmE2OTlkZTk1NzI1ZWYxNWY4Y2M2MjVhMjg=
9
+ NDJkYWMxZDI4YzdhMWY2ZTVhYWRjMjU1YTg5ZmYyMTQwNjRkZjkwMGIzMTBl
10
+ Y2VlMjgzNmM5OTVjMDM1N2I3YTU1Y2Y2OGRkZGRkOWE3NWVjYjg4ZGE5ODc5
11
+ OTU2ZTk2MGU2NWVkZTVlMTRmY2MxOTVlZmVkZmUxNDEzZDViOGM=
12
12
  data.tar.gz: !binary |-
13
- NmRmMWZiMDE4MGM5M2RjNjY4M2IzNGM3YjhlY2UxZjhhYTU1Yjg4ZjEwNzA0
14
- YTVkYTRkMDRjZjI5ZDVjOGYwOWNiODU0NzRlMTE2YTExYTdmZjBkYWE0ZjJk
15
- NzdkMmE3ZmQ1OGQ0MTEyYWZlNmY4MjYwMjdiMzFkNjk3Nzg1N2Q=
13
+ ZjZjNzQ5Nzc5YjdmM2I3OTBiNzI0NDQ4NDM1Y2RiYzk3ZjAzYzg1MzQ5NGVh
14
+ NjExYmM5ZmNlOWEzODNiYjIwNzgyYjVmOWMyYzE1YmI2NjY2ODJkMjE4YzE3
15
+ OTczMjBjOGFiNDM2YTQ1NWY4ODhhYWFiMTg4ZDkzZDBjYjA0NmE=
data/CHANGES CHANGED
@@ -1,3 +1,7 @@
1
+ 2014-05-20 Clinton Wolfe 0.6.1
2
+ Fixed issue #6, inconsistent behavior for 'enum' and 'type' checks when a attr has a nil value
3
+ Fixed issue #5, pathfinder breaking when given a path containing a stringified integer and no wildcards
4
+
1
5
  2014-01-27 Clinton Wolfe 0.6.0
2
6
  Loosened runtime dep on chef
3
7
 
data/README.md CHANGED
@@ -50,6 +50,8 @@ Each rule gets a unique name. Each entry is hash structure with the following k
50
50
  The remaining entries describe criteria to enforce on the value of the attribute(s)
51
51
  referenced by 'path'. You may list zero or more.
52
52
 
53
+ Note that nil is permitted as a value by all checks, except the 'required' check (which performs nilness checks) and the 'proc' check (which implements arbitrary user behavior).
54
+
53
55
  #### type
54
56
 
55
57
  Checks type of value. One of 'string', 'number', 'boolean', 'hash', 'array'.
@@ -64,7 +66,7 @@ Integer. Fails for all but Hash and Array. For Hash and Array, maximum number
64
66
 
65
67
  #### present
66
68
 
67
- Boolean. If true, fails if the path matches zero attributes. If false, fails if the path matches nonzero attributes. Does not consider nilness, only existence of attribute key(s). See also required.
69
+ Boolean. If true, fails if the path matches zero attributes. If false, fails if the path matches nonzero attributes. This is most useful for enforcing deprecated attributes. Does not consider nilness, only existence of attribute key(s). See also required.
68
70
 
69
71
  #### regex
70
72
 
@@ -42,10 +42,7 @@ class Chef
42
42
  String,
43
43
  ].any? { |k| val.kind_of?(k) }
44
44
  end
45
-
46
-
47
-
48
-
45
+
49
46
  end
50
47
  end
51
48
  end
@@ -15,7 +15,7 @@ class Chef
15
15
  def check(attrset)
16
16
  violations = []
17
17
  attrset.each do |path, value|
18
- if val_scalar?(value)
18
+ if val_scalar?(value) && ! value.nil?
19
19
  unless check_arg.include?(value)
20
20
  violations.push Chef::Attribute::Validator::Violation.new(rule_name, path, "Attribute's value is '#{value}', which is not one of '#{check_arg.map{ |e| e.to_s }.join(',')} '")
21
21
  end
@@ -33,6 +33,7 @@ class Chef
33
33
  }
34
34
 
35
35
  attrset.each do |path, value|
36
+ next if value.nil?
36
37
  unless klasses[check_arg].any? {|k| value.kind_of?(k) }
37
38
  violations.push Chef::Attribute::Validator::Violation.new(rule_name, path, "Attribute's value is '#{value}', which does not appear to be the right type - expected '#{check_arg}'")
38
39
  end
@@ -1,7 +1,7 @@
1
1
  class Chef
2
2
  class Attribute
3
3
  class Validator
4
- VERSION = "0.6.0"
4
+ VERSION = "0.6.1"
5
5
  end
6
6
  end
7
7
  end
@@ -23,9 +23,6 @@ class Chef
23
23
  # Since we begin with /, the first element is ""
24
24
  if steps[0] == "" then steps.shift end
25
25
 
26
- # Promote integer strings to integers
27
- steps.map! { |s| s.match(/^\d+$/) ? s.to_i : s }
28
-
29
26
  steps
30
27
  end
31
28
 
@@ -35,11 +32,27 @@ class Chef
35
32
  nv = node
36
33
  steps = slashpath_to_steps(slashpath)
37
34
  while steps.size > 0
38
- nv = nv[steps.shift]
35
+ step = steps.shift
36
+ if nv.kind_of?(Chef::Node::ImmutableArray) then
37
+ step = convert_step_to_integer(step)
38
+ return nil if step.nil? # Given a non-int path step for an array...
39
+ end
40
+ nv = nv[step]
39
41
  end
40
42
  nv
41
43
  end
42
44
 
45
+ def convert_step_to_integer(step)
46
+ if step.match(/^\d+$/) then
47
+ # Treat things that start with leading zeros as strings, not as integers. This supports
48
+ # having attributes like '00', and calling that an error if you try to access the 00 element of an array.
49
+ return nil if step.match(/^0+\d+$/)
50
+ return step.to_i
51
+ else
52
+ return nil
53
+ end
54
+ end
55
+
43
56
  def path_exists_by_slashpath? (slashpath)
44
57
  nv = node
45
58
  steps = slashpath_to_steps(slashpath)
@@ -47,10 +60,12 @@ class Chef
47
60
  step = steps.shift
48
61
 
49
62
  if nv.kind_of?(Chef::Node::ImmutableArray) then
50
- # TODO: what if the step isn't an int?
63
+
64
+ step_as_int = convert_step_to_integer(step)
65
+ return false if step_as_int.nil? # Given a non-int path step for an array...
51
66
 
52
- if nv.size > step then
53
- nv = nv[step]
67
+ if nv.size > step_as_int then
68
+ nv = nv[step_as_int]
54
69
  else
55
70
  # Array not long enough
56
71
  return false
@@ -8,13 +8,13 @@ default['fruits']['a'] = 'banana'
8
8
  default['fruits']['b'] = 'gichee'
9
9
  default['fruits']['c'] = 'tomato'
10
10
 
11
- default['cats'][0] = 'leopard'
12
- default['cats'][1] = 'puma'
13
- default['cats'][2] = 'mountain lion'
14
- default['cats'][3] = 'catamount'
15
-
11
+ default['cats'] = [ 'leopard', 'puma', 'mountain lion', 'catamount' ]
16
12
 
17
13
  rules = default['attribute-validator']['rules']
14
+ rules['nil'] = {
15
+ 'path' => '/nil',
16
+ 'enum' => ['a'],
17
+ }
18
18
  rules['empty-a'] = {
19
19
  'path' => '/empty',
20
20
  'enum' => ['a'],
@@ -20,7 +20,6 @@ proc_array_looks_fibonacci = Proc.new do |rule_name, attrset|
20
20
  prev1 = 0
21
21
  prev2 = 1
22
22
  attrset.each do |path, value|
23
- # binding.pry
24
23
  unless value == prev1 + prev2
25
24
  violations.push Chef::Attribute::Validator::Violation.new(rule_name, path, 'Stopped looking like a fibonacci sequence')
26
25
  end
@@ -0,0 +1,12 @@
1
+ default['array'] = [ { 'child0' => 'value' }, { 'child1' => 'value' } ]
2
+ default['hash']['0']['child0'] = 'value'
3
+ default['hash']['1']['child1'] = 'value'
4
+ default['hash']['00']['child00'] = 'value'
5
+ default['hash']['01']['child01'] = 'value'
6
+
7
+ default['deeper_array']['poney'] = [ { 'child0' => 'value' }, { 'child1' => 'value' } ]
8
+ default['deeper_hash']['poney']['0']['child0'] = 'value'
9
+ default['deeper_hash']['poney']['1']['child1'] = 'value'
10
+ default['deeper_hash']['poney']['00']['child00'] = 'value'
11
+ default['deeper_hash']['poney']['01']['child01'] = 'value'
12
+
@@ -0,0 +1,107 @@
1
+ require_relative './spec_helper.rb'
2
+
3
+ describe "Issue #4 - When the search path contains a stringified integer" do
4
+ let(:node) { CAVHelper.load_fixture_attributes('regression_4_integer_in_path') }
5
+
6
+ context "when there is no wildcard in the path" do
7
+
8
+ context "when the path spec contains a single-digit int" do
9
+ context "when the targetted attribute is an array" do
10
+ let(:exp) { Chef::Attribute::Validator::WildcardExpander.choose('/array/0/child0', node) }
11
+ it "should find the entry" do
12
+ expect(exp.expand_all).to include('/array/0/child0')
13
+ end
14
+ end
15
+ context "when the targetted attribute is a hash" do
16
+ let(:exp) { Chef::Attribute::Validator::WildcardExpander.choose('/hash/0/child0', node) }
17
+ it "should find the entry" do
18
+ expect(exp.expand_all).to include('/hash/0/child0')
19
+ end
20
+ end
21
+ end
22
+
23
+ context "when the path spec contains a two-digit int" do
24
+ context "when the targetted attribute is an array" do
25
+ let(:exp) { Chef::Attribute::Validator::WildcardExpander.choose('/array/00/child0', node) }
26
+ it "should NOT find the entry" do
27
+ expect(exp.expand_all).not_to include('/array/00/child0')
28
+ end
29
+ end
30
+ context "when the targetted attribute is a hash" do
31
+ let(:exp) { Chef::Attribute::Validator::WildcardExpander.choose('/hash/00/child00', node) }
32
+ it "should find the entry" do
33
+ expect(exp.expand_all).to include('/hash/00/child00')
34
+ end
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ context "when there is a wildcard on the int segment" do
41
+
42
+ context "when the path spec contains a single-digit int" do
43
+ context "when the targetted attribute is an array" do
44
+ let(:exp) { Chef::Attribute::Validator::WildcardExpander.choose('/array/*/child0', node) }
45
+ it "should find the entry" do
46
+ expect(exp.expand_all).to include('/array/0/child0')
47
+ end
48
+ end
49
+ context "when the targetted attribute is a hash" do
50
+ let(:exp) { Chef::Attribute::Validator::WildcardExpander.choose('/hash/*/child0', node) }
51
+ it "should find the entry" do
52
+ expect(exp.expand_all).to include('/hash/0/child0')
53
+ end
54
+ end
55
+ end
56
+
57
+ context "when the path spec contains a two-digit int" do
58
+ context "when the targetted attribute is an array" do
59
+ let(:exp) { Chef::Attribute::Validator::WildcardExpander.choose('/array/*/child0', node) }
60
+ it "should NOT find the entry" do
61
+ expect(exp.expand_all).not_to include('/array/00/child0')
62
+ end
63
+ end
64
+ context "when the targetted attribute is a hash" do
65
+ let(:exp) { Chef::Attribute::Validator::WildcardExpander.choose('/hash/*/child00', node) }
66
+ it "should find the entry" do
67
+ expect(exp.expand_all).to include('/hash/00/child00')
68
+ end
69
+ end
70
+ end
71
+
72
+ end
73
+
74
+ context "when there is a wildcard prior to the int segment" do
75
+
76
+ context "when the path spec contains a single-digit int" do
77
+ context "the targetted attribute is an array" do
78
+ let(:exp) { Chef::Attribute::Validator::WildcardExpander.choose('/deeper_array/*/0/child0', node) }
79
+ it "should find the entry" do
80
+ expect(exp.expand_all).to include('/deeper_array/poney/0/child0')
81
+ end
82
+ end
83
+ context "when the targetted attribute is a hash" do
84
+ let(:exp) { Chef::Attribute::Validator::WildcardExpander.choose('/deeper_hash/*/0/child0', node) }
85
+ it "should find the entry" do
86
+ expect(exp.expand_all).to include('/deeper_hash/poney/0/child0')
87
+ end
88
+ end
89
+ end
90
+
91
+ context "when the path spec contains a two-digit int" do
92
+ context "the targetted attribute is an array" do
93
+ let(:exp) { Chef::Attribute::Validator::WildcardExpander.choose('/deeper_array/*/00/child0', node) }
94
+ it "should NOT find the entry" do
95
+ expect(exp.expand_all).not_to include('/deeper_array/poney/00/child0')
96
+ end
97
+ end
98
+ context "when the targetted attribute is a hash" do
99
+ let(:exp) { Chef::Attribute::Validator::WildcardExpander.choose('/deeper_hash/*/00/child00', node) }
100
+ it "should find the entry" do
101
+ expect(exp.expand_all).to include('/deeper_hash/poney/00/child00')
102
+ end
103
+ end
104
+ end
105
+
106
+ end
107
+ end
@@ -0,0 +1,17 @@
1
+
2
+ require 'chef/node'
3
+
4
+ require_relative '../../lib/chef-attribute-validator'
5
+
6
+ module CAVHelper
7
+ def load_fixture_attributes(filename, node = nil)
8
+ node ||= Chef::Node.new
9
+ filepath = File.join(File.dirname(__FILE__), '..', 'fixtures', filename)
10
+ filepath = filepath.gsub(/\.rb$/, '') + '.rb'
11
+ node.from_file(filepath)
12
+ node
13
+ end
14
+
15
+ module_function :load_fixture_attributes
16
+
17
+ end
@@ -60,7 +60,7 @@ describe Chef::Attribute::Validator::AttributeSet do
60
60
  end
61
61
  let(:ats) { Chef::Attribute::Validator::AttributeSet.new(node, '/*') }
62
62
  it "should be able to list all root elements" do
63
- expect(ats.size).to eq 7
63
+ expect(ats.size).to eq 6
64
64
  end
65
65
  end
66
66
 
@@ -47,6 +47,10 @@ describe "'enum' check" do
47
47
  expect(av.validate_rule('empty-empty-match')).to be_empty
48
48
  end
49
49
 
50
+ it "should not violate on a nil-valued entry" do
51
+ expect(av.validate_rule('nil')).to be_empty
52
+ end
53
+
50
54
  it "should not violate on a hash-valued entry" do
51
55
  expect(av.validate_rule('hash')).to be_empty
52
56
  end
@@ -243,5 +243,4 @@ describe "'looks_like' check" do
243
243
 
244
244
  end
245
245
 
246
-
247
246
  end
@@ -51,10 +51,6 @@ describe "'proc' check" do
51
51
  expect(av.validate_rule('nil-always-fail')).not_to be_empty
52
52
  end
53
53
 
54
- it "a violation should include the correct rule name" do
55
- expect(av.validate_rule('nil-always-fail')[0].rule_name).to eql 'nil-always-fail'
56
- end
57
-
58
54
  it "fibonacci scanner should not violate on a correct fib sequence" do
59
55
  expect(av.validate_rule('valid-fibo')).to be_empty
60
56
  end
@@ -63,6 +59,9 @@ describe "'proc' check" do
63
59
  expect(av.validate_rule('invalid-fibo')).not_to be_empty
64
60
  end
65
61
 
62
+ it "a violation should include the correct rule name" do
63
+ expect(av.validate_rule('invalid-fibo')[0].rule_name).to eql 'invalid-fibo'
64
+ end
66
65
 
67
66
  end
68
67
 
@@ -38,6 +38,10 @@ describe "'regex' check" do
38
38
  expect(av.validate_rule('empty-empty')).to be_empty
39
39
  end
40
40
 
41
+ it "/foo/ should not violate on nil" do
42
+ expect(av.validate_rule('foo-nil')).to be_empty
43
+ end
44
+
41
45
  it "/foo/ should not violate on foo" do
42
46
  expect(av.validate_rule('foo-foo')).to be_empty
43
47
  end
@@ -27,8 +27,8 @@ describe "'type' check" do
27
27
  expect(av.validate_rule('string-number')).not_to be_empty
28
28
  end
29
29
 
30
- it "should violate on nil" do
31
- expect(av.validate_rule('string-nil')).not_to be_empty
30
+ it "should not violate on nil" do
31
+ expect(av.validate_rule('string-nil')).to be_empty
32
32
  end
33
33
 
34
34
  it "should violate on array" do
@@ -57,8 +57,8 @@ describe "'type' check" do
57
57
  expect(av.validate_rule('number-as-string')).not_to be_empty
58
58
  end
59
59
 
60
- it "should violate on nil" do
61
- expect(av.validate_rule('number-nil')).not_to be_empty
60
+ it "should not violate on nil" do
61
+ expect(av.validate_rule('number-nil')).to be_empty
62
62
  end
63
63
 
64
64
  it "should violate on array" do
@@ -99,8 +99,8 @@ describe "'type' check" do
99
99
  expect(av.validate_rule('boolean-empty')).not_to be_empty
100
100
  end
101
101
 
102
- it "should violate on nil" do
103
- expect(av.validate_rule('boolean-nil')).not_to be_empty
102
+ it "should not violate on nil" do
103
+ expect(av.validate_rule('boolean-nil')).to be_empty
104
104
  end
105
105
 
106
106
  it "should violate on array" do
@@ -141,8 +141,8 @@ describe "'type' check" do
141
141
  expect(av.validate_rule('array-zero')).not_to be_empty
142
142
  end
143
143
 
144
- it "should violate on nil" do
145
- expect(av.validate_rule('array-nil')).not_to be_empty
144
+ it "should not violate on nil" do
145
+ expect(av.validate_rule('array-nil')).to be_empty
146
146
  end
147
147
 
148
148
  it "should violate on hash" do
@@ -179,8 +179,8 @@ describe "'type' check" do
179
179
  expect(av.validate_rule('hash-zero')).not_to be_empty
180
180
  end
181
181
 
182
- it "should violate on nil" do
183
- expect(av.validate_rule('hash-nil')).not_to be_empty
182
+ it "should not violate on nil" do
183
+ expect(av.validate_rule('hash-nil')).to be_empty
184
184
  end
185
185
 
186
186
  it "should violate on array" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-attribute-validator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Clinton Wolfe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-28 00:00:00.000000000 Z
11
+ date: 2014-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,16 @@ dependencies:
16
16
  requirements:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: '1.3'
19
+ version: !binary |-
20
+ MS4z
20
21
  type: :development
21
22
  prerelease: false
22
23
  version_requirements: !ruby/object:Gem::Requirement
23
24
  requirements:
24
25
  - - ~>
25
26
  - !ruby/object:Gem::Version
26
- version: '1.3'
27
+ version: !binary |-
28
+ MS4z
27
29
  - !ruby/object:Gem::Dependency
28
30
  name: rake
29
31
  requirement: !ruby/object:Gem::Requirement
@@ -130,11 +132,14 @@ files:
130
132
  - test/fixtures/expander_brutal_deep_hash.rb
131
133
  - test/fixtures/expander_brutal_deep_mixed.rb
132
134
  - test/fixtures/expander_brutal_flat.rb
135
+ - test/fixtures/regression_4_integer_in_path.rb
133
136
  - test/fixtures/rules_empty.rb
134
137
  - test/fixtures/rules_missing_path.rb
135
138
  - test/fixtures/rules_no_check.rb
136
139
  - test/fixtures/rules_type_and_min_children.rb
137
140
  - test/fixtures/rules_type_check.rb
141
+ - test/regression/4-integer-in-path.rb
142
+ - test/regression/spec_helper.rb
138
143
  - test/unit/attr_set_spec.rb
139
144
  - test/unit/attr_set_spec_wildcard.rb
140
145
  - test/unit/check_child_count_spec.rb
@@ -216,11 +221,14 @@ test_files:
216
221
  - test/fixtures/expander_brutal_deep_hash.rb
217
222
  - test/fixtures/expander_brutal_deep_mixed.rb
218
223
  - test/fixtures/expander_brutal_flat.rb
224
+ - test/fixtures/regression_4_integer_in_path.rb
219
225
  - test/fixtures/rules_empty.rb
220
226
  - test/fixtures/rules_missing_path.rb
221
227
  - test/fixtures/rules_no_check.rb
222
228
  - test/fixtures/rules_type_and_min_children.rb
223
229
  - test/fixtures/rules_type_check.rb
230
+ - test/regression/4-integer-in-path.rb
231
+ - test/regression/spec_helper.rb
224
232
  - test/unit/attr_set_spec.rb
225
233
  - test/unit/attr_set_spec_wildcard.rb
226
234
  - test/unit/check_child_count_spec.rb
@@ -234,4 +242,3 @@ test_files:
234
242
  - test/unit/expanders/brutal_regex_spec.rb
235
243
  - test/unit/rule_parse_spec.rb
236
244
  - test/unit/spec_helper.rb
237
- has_rdoc: