chef-attribute-validator 0.2.0 → 0.3.0

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
- MThmOWZjYmNhMzI0ODZiODM4ZmNmMWYzOGVkYjNjZDIyMWMzZGU0OA==
4
+ NDNkM2Y5MDMwZTEwNmYwN2Q0ZmQ3NzkzYzQyN2NlNjE2ODYwNTc1Mg==
5
5
  data.tar.gz: !binary |-
6
- ZWU3YmQzMGNkYmQ2Y2ExYTE1NWQ4MWY1MmUzNDVhMTljNjAzNDE0MA==
6
+ ZjNiMGQwNDZkM2Y0MmI2OGFjZWM3MTM0MjI2ZDA2OGRhNTFkZWZjNg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZDFiZjFiNmUyZDE2MTljOTI3ZWNiNDI5ZjVjN2ZmNTAyYTVhMDdiMzMwZmU1
10
- MGZmODUxZDIyNjJhNjJhMmMzODYzMjMwZWFkMDIyNzg3YWU5YWZkYjQ1Mjg3
11
- YzU5YTJiNjM3NDM0Y2EwM2FlYjdmMGZmNjEzMzU3M2FiYTU2OGI=
9
+ NWY1MTBhNTk3MTU2MTQ4NWFkZDk5MjY5NTdlZTY2ODI1YTQ4ZDcwYzU5MGQx
10
+ NGFlMmE1OTZhZjdiZWIwZDNiZGY1YzI0YWY3MjAzYTlhYTI0YjliNmM0NzA3
11
+ NzUwNzczMjI1OWVjNzFkNjdiNDYyYzE4NDAxZWUyYWYxNGZkNDA=
12
12
  data.tar.gz: !binary |-
13
- MmVmZWQ1YzA2M2ZlOTkxMjE2ZDg5ZGE0MmI0NGRkZTcwNDQ3M2I5YWRhYTdk
14
- OTY3N2E3ZjZhN2I4NTk5YTc2NjBlYjk5ZDViMWI5M2U3NDM4M2NjYjlmNTNi
15
- NTdjNzJmMzI4MWM5NDNjYWQ0ZmU3MGZmYWU5NmRjY2ZlYmQ0YjU=
13
+ ZWM3YzFjMjRhZTY2MjYzNjI3YzhhZmU4ZGY4ZDNhMGExYmY5YzMzZDljYmQw
14
+ NWQzNThjN2UwOWI3YjkyNTQ1YTJhOWRhZjFjZTIxZGJiYjJjNjBkMWYzZjdl
15
+ ZTliYWRhOGQ5ZDk2ZjExYjZkM2Q0ZTdiMjljMTVhZjJjOTViOTQ=
data/CHANGES CHANGED
@@ -1,3 +1,7 @@
1
+ 2013-11-12 Clinton Wolfe 0.3.0
2
+ Support for enum check
3
+ Support for proc check
4
+
1
5
  2013-11-12 Clinton Wolfe 0.2.0
2
6
  Support for wildcards - *, **, ?
3
7
  Crude implementation using brute force and regexes
data/README.md CHANGED
@@ -56,6 +56,8 @@ referenced by 'path'. You may list zero or more.
56
56
  regex - Regexp. Applies given regex to the value. Ignored for Hash and Array. See looks_like for a selection of canned regexen.
57
57
  required - Boolean. If true, fails if the path matches zero attributes, or the value is nil, or the value is the empty string, or if the value is an empty array or empty hash. No-op if false (use present => false to enforce absence).
58
58
  looks_like - String, one of 'url', 'ip'. Applies canned regexes (or more sophisticated matchers).
59
+ enum - Array, a set of possible values.
60
+ proc - a Proc, which should take two args - a string rule name, and a Chef::Attribute::Validator::AttributeSet. You can treat the attribute set as a hash - its each() methods will yield path, value pairs. The proc should return a possibly empty array of Chef::Attribute::Validator::Violations.
59
61
 
60
62
  ## Referencing Attributes
61
63
 
@@ -0,0 +1,31 @@
1
+ class Chef
2
+ class Attribute
3
+ class Validator
4
+ class Check
5
+ class Enum < Check
6
+
7
+ register_check('enum', Enum)
8
+
9
+ def validate_check_arg
10
+ unless check_arg.kind_of?(Array)
11
+ raise "Bad 'enum' check argument '#{check_arg}' for rule '#{rule_name}' - expected an Array"
12
+ end
13
+ end
14
+
15
+ def check(attrset)
16
+ violations = []
17
+ attrset.each do |path, value|
18
+ if val_scalar?(value)
19
+ unless check_arg.include?(value)
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
+ end
22
+ end
23
+ end
24
+ violations
25
+ end
26
+
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ class Chef
2
+ class Attribute
3
+ class Validator
4
+ class Check
5
+ class Proc < Check
6
+
7
+ register_check('proc', Proc)
8
+
9
+ def validate_check_arg
10
+ unless check_arg.kind_of?(::Proc)
11
+ raise "Bad 'proc' check argument '#{check_arg}' for rule '#{rule_name}' - expected a Proc"
12
+ end
13
+ unless check_arg.arity == 2
14
+ raise "Bad 'proc' check argument '#{check_arg}' for rule '#{rule_name}' - Proc must take exactly two arguments, a rule name and an AttributeSet."
15
+ end
16
+ end
17
+
18
+ def check(attrset)
19
+ check_arg.call(rule_name, attrset)
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,7 +1,7 @@
1
1
  class Chef
2
2
  class Attribute
3
3
  class Validator
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
6
6
  end
7
7
  end
@@ -39,7 +39,7 @@ class Chef
39
39
  end
40
40
  else
41
41
  node_cursor.keys.each do |key|
42
- child_paths.push prefix + '/' + key
42
+ child_paths.push prefix + '/' + key.to_s
43
43
  if node_cursor[key].kind_of?(Mash) || node_cursor[key].kind_of?(Array)
44
44
  child_paths += find_all_slashpaths(prefix + '/' + key, node_cursor[key])
45
45
  end
@@ -0,0 +1,6 @@
1
+ rules = default['attribute-validator']['rules']
2
+ rules['check-enum-array-empty'] = {
3
+ 'path' => '/empty',
4
+ 'enum' => [],
5
+ }
6
+
@@ -0,0 +1,7 @@
1
+ rules = default['attribute-validator']['rules']
2
+ rules['check-enum-array-mixed'] = {
3
+ 'path' => '/empty',
4
+ 'enum' => ['a', :b, 3],
5
+ }
6
+
7
+
@@ -0,0 +1,6 @@
1
+ rules = default['attribute-validator']['rules']
2
+ rules['check-enum-array-empty'] = {
3
+ 'path' => '/empty',
4
+ 'enum' => ['a', 'b', 'c'],
5
+ }
6
+
@@ -0,0 +1,52 @@
1
+ default['empty'] = ""
2
+ default['nil'] = nil
3
+
4
+ default['not']['a']['scalar']['here'] = {}
5
+
6
+
7
+ default['fruits']['a'] = 'banana'
8
+ default['fruits']['b'] = 'gichee'
9
+ default['fruits']['c'] = 'tomato'
10
+
11
+ default['cats'][0] = 'leopard'
12
+ default['cats'][1] = 'puma'
13
+ default['cats'][2] = 'mountain lion'
14
+ default['cats'][3] = 'catamount'
15
+
16
+
17
+ rules = default['attribute-validator']['rules']
18
+ rules['empty-a'] = {
19
+ 'path' => '/empty',
20
+ 'enum' => ['a'],
21
+ }
22
+ rules['empty-empty'] = {
23
+ 'path' => '/empty',
24
+ 'enum' => [],
25
+ }
26
+ rules['empty-empty-match'] = {
27
+ 'path' => '/empty',
28
+ 'enum' => [''],
29
+ }
30
+ rules['hash'] = {
31
+ 'path' => '/not/a/scalar',
32
+ 'enum' => [ 'a' ],
33
+ }
34
+ rules['fruits'] = {
35
+ 'path' => '/fruits/a',
36
+ 'enum' => ['banana', 'gichee', 'apple'],
37
+ }
38
+ rules['mixed-fruits'] = {
39
+ 'path' => '/fruits/b',
40
+ 'enum' => [:banana, 'gichee', 23],
41
+ }
42
+
43
+ rules['today-its-a-vegetable'] = {
44
+ 'path' => '/fruits/c',
45
+ 'enum' => ['banana', 'gichee', 'apple'],
46
+ }
47
+
48
+ rules['cougars'] = {
49
+ 'path' => '/cats/*',
50
+ 'enum' => ['leopard', 'puma', 'mountain lion', 'catamount'],
51
+ }
52
+
@@ -0,0 +1,6 @@
1
+ rules = default['attribute-validator']['rules']
2
+ rules['check-enum-nil'] = {
3
+ 'path' => '/empty',
4
+ 'enum' => nil,
5
+ }
6
+
@@ -0,0 +1,6 @@
1
+ rules = default['attribute-validator']['rules']
2
+ rules['check-enum-string'] = {
3
+ 'path' => '/empty',
4
+ 'enum' => 'lol, l8r, <3',
5
+ }
6
+
@@ -0,0 +1,10 @@
1
+ rules = default['attribute-validator']['rules']
2
+ rules['check-proc-nil'] = {
3
+ 'path' => '/nope',
4
+ 'proc' => Proc.new do
5
+ []
6
+ end
7
+
8
+
9
+ }
10
+
@@ -0,0 +1,10 @@
1
+ rules = default['attribute-validator']['rules']
2
+ rules['check-proc-nil'] = {
3
+ 'path' => '/nope',
4
+ 'proc' => Proc.new do |attrs|
5
+ []
6
+ end
7
+
8
+
9
+ }
10
+
@@ -0,0 +1,10 @@
1
+ rules = default['attribute-validator']['rules']
2
+ rules['check-proc-nil'] = {
3
+ 'path' => '/nope',
4
+ 'proc' => Proc.new do |a,b|
5
+ []
6
+ end
7
+
8
+
9
+ }
10
+
@@ -0,0 +1,10 @@
1
+ rules = default['attribute-validator']['rules']
2
+ rules['check-proc-nil'] = {
3
+ 'path' => '/nope',
4
+ 'proc' => Proc.new do |a,b,c|
5
+ []
6
+ end
7
+
8
+
9
+ }
10
+
@@ -0,0 +1,63 @@
1
+ default['nil'] = nil
2
+ default['bunnies'] = [1, 2, 3, 5, 8]
3
+ default['rabbot'] = [1, 2, 3, 5, 8, 0]
4
+
5
+
6
+ rules = default['attribute-validator']['rules']
7
+
8
+ proc_never_fail = Proc.new do |rule_name, attrset|
9
+ # No matter what, return no violations
10
+ []
11
+ end
12
+
13
+ proc_always_fail = Proc.new do |rule_name, attrset|
14
+ # No matter what, return a violation
15
+ [ Chef::Attribute::Validator::Violation.new(rule_name, '/meh', 'I always fail') ]
16
+ end
17
+
18
+ proc_array_looks_fibonacci = Proc.new do |rule_name, attrset|
19
+ violations = []
20
+ prev1 = 0
21
+ prev2 = 1
22
+ attrset.each do |path, value|
23
+ # binding.pry
24
+ unless value == prev1 + prev2
25
+ violations.push Chef::Attribute::Validator::Violation.new(rule_name, path, 'Stopped looking like a fibonacci sequence')
26
+ end
27
+ prev1 = prev2
28
+ prev2 = value
29
+ end
30
+ violations
31
+ end
32
+
33
+
34
+ rules['missing-never-fail'] = {
35
+ 'path' => '/nope',
36
+ 'proc' => proc_never_fail
37
+ }
38
+
39
+ rules['nil-never-fail'] = {
40
+ 'path' => '/nil',
41
+ 'proc' => proc_never_fail
42
+ }
43
+
44
+ rules['nil-always-fail'] = {
45
+ 'path' => '/nil',
46
+ 'proc' => proc_always_fail
47
+ }
48
+
49
+ rules['missing-always-fail'] = {
50
+ 'path' => '/nope',
51
+ 'proc' => proc_always_fail
52
+ }
53
+
54
+ rules['valid-fibo'] = {
55
+ 'path' => '/bunnies/*',
56
+ 'proc' => proc_array_looks_fibonacci
57
+ }
58
+ rules['invalid-fibo'] = {
59
+ 'path' => '/rabbot/*',
60
+ 'proc' => proc_array_looks_fibonacci
61
+ }
62
+
63
+
@@ -0,0 +1,6 @@
1
+ rules = default['attribute-validator']['rules']
2
+ rules['check-proc-nil'] = {
3
+ 'path' => '/nope',
4
+ 'proc' => nil,
5
+ }
6
+
@@ -0,0 +1,72 @@
1
+ require_relative './spec_helper'
2
+
3
+ describe "'enum' check" do
4
+
5
+ describe "check registry" do
6
+ it "should be present in the Check registry" do
7
+ expect(Chef::Attribute::Validator::Check.list_check_types).to include('enum')
8
+ end
9
+ end
10
+
11
+ describe "check_arg checks" do
12
+ it "should accept an empty array" do
13
+ node = CAVHelper.load_fixture_attributes('check_enum_array_empty')
14
+ expect { Chef::Attribute::Validator.new(node) }.not_to raise_error
15
+ end
16
+ it "should accept an array of strings" do
17
+ node = CAVHelper.load_fixture_attributes('check_enum_array_strings')
18
+ expect { Chef::Attribute::Validator.new(node) }.not_to raise_error
19
+ end
20
+ it "should accept a mixed array" do
21
+ node = CAVHelper.load_fixture_attributes('check_enum_array_mixed')
22
+ expect { Chef::Attribute::Validator.new(node) }.not_to raise_error
23
+ end
24
+ it "should reject a string" do
25
+ node = CAVHelper.load_fixture_attributes('check_enum_string')
26
+ expect { Chef::Attribute::Validator.new(node) }.to raise_error
27
+ end
28
+ it "should reject a nil" do
29
+ node = CAVHelper.load_fixture_attributes('check_enum_nil')
30
+ expect { Chef::Attribute::Validator.new(node) }.to raise_error
31
+ end
32
+ end
33
+
34
+ describe "assorted arrays" do
35
+ let(:node) { CAVHelper.load_fixture_attributes('check_enum_assorted') }
36
+ let(:av) { Chef::Attribute::Validator.new(node) }
37
+
38
+ it "should violate on an empty string with an empty enum list" do
39
+ expect(av.validate_rule('empty-empty')).not_to be_empty
40
+ end
41
+
42
+ it "should violate on an empty string with a non-empty enum list" do
43
+ expect(av.validate_rule('empty-a')).not_to be_empty
44
+ end
45
+
46
+ it "should not violate on an empty string with a '' enum list" do
47
+ expect(av.validate_rule('empty-empty-match')).to be_empty
48
+ end
49
+
50
+ it "should not violate on a hash-valued entry" do
51
+ expect(av.validate_rule('hash')).to be_empty
52
+ end
53
+
54
+ it "should not violate on a simple entry" do
55
+ expect(av.validate_rule('fruits')).to be_empty
56
+ end
57
+
58
+ it "should not violate on a mixed entry" do
59
+ expect(av.validate_rule('mixed-fruits')).to be_empty
60
+ end
61
+
62
+ it "should not violate when running over an array attribute" do
63
+ expect(av.validate_rule('cougars')).to be_empty
64
+ end
65
+
66
+ it "should violate when a tomato is not a fruit" do
67
+ expect(av.validate_rule('today-its-a-vegetable')).not_to be_empty
68
+ end
69
+
70
+ end
71
+
72
+ end
@@ -0,0 +1,69 @@
1
+ require_relative './spec_helper'
2
+
3
+ describe "'proc' check" do
4
+
5
+ describe "check registry" do
6
+ it "should be present in the Check registry" do
7
+ expect(Chef::Attribute::Validator::Check.list_check_types).to include('proc')
8
+ end
9
+ end
10
+
11
+ describe "check_arg checks" do
12
+ it "should reject nil" do
13
+ node = CAVHelper.load_fixture_attributes('check_proc_nil')
14
+ expect { Chef::Attribute::Validator.new(node) }.to raise_error
15
+ end
16
+ it "should reject a 0-arg Proc" do
17
+ node = CAVHelper.load_fixture_attributes('check_proc_arity0')
18
+ expect { Chef::Attribute::Validator.new(node) }.to raise_error
19
+ end
20
+ it "should reject a 1-arg Proc" do
21
+ node = CAVHelper.load_fixture_attributes('check_proc_arity1')
22
+ expect { Chef::Attribute::Validator.new(node) }.to raise_error
23
+ end
24
+ it "should accept a 2-arg Proc" do
25
+ node = CAVHelper.load_fixture_attributes('check_proc_arity2')
26
+ expect { Chef::Attribute::Validator.new(node) }.not_to raise_error
27
+ end
28
+ it "should reject a 3-arg Proc" do
29
+ node = CAVHelper.load_fixture_attributes('check_proc_arity3')
30
+ expect { Chef::Attribute::Validator.new(node) }.to raise_error
31
+ end
32
+ end
33
+
34
+ describe "assorted procs" do
35
+ let(:node) { CAVHelper.load_fixture_attributes('check_proc_assorted') }
36
+ let(:av) { Chef::Attribute::Validator.new(node) }
37
+
38
+ it "should not violate on a missing attribute with a never-fail proc" do
39
+ expect(av.validate_rule('missing-never-fail')).to be_empty
40
+ end
41
+
42
+ it "should not violate on a nil attribute with a never-fail proc" do
43
+ expect(av.validate_rule('nil-never-fail')).to be_empty
44
+ end
45
+
46
+ it "should violate on a missing attribute with an always-fail proc" do
47
+ expect(av.validate_rule('missing-always-fail')).not_to be_empty
48
+ end
49
+
50
+ it "should violate on a nil attribute with an always-fail proc" do
51
+ expect(av.validate_rule('nil-always-fail')).not_to be_empty
52
+ end
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
+ it "fibonacci scanner should not violate on a correct fib sequence" do
59
+ expect(av.validate_rule('valid-fibo')).to be_empty
60
+ end
61
+
62
+ it "fibonacci scanner should violate on a incorrect fib sequence" do
63
+ expect(av.validate_rule('invalid-fibo')).not_to be_empty
64
+ end
65
+
66
+
67
+ end
68
+
69
+ end
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.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Clinton Wolfe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-12 00:00:00.000000000 Z
11
+ date: 2013-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -74,9 +74,11 @@ files:
74
74
  - lib/chef-attribute-validator.rb
75
75
  - lib/chef-attribute-validator/attribute_set.rb
76
76
  - lib/chef-attribute-validator/check.rb
77
+ - lib/chef-attribute-validator/checks/enum.rb
77
78
  - lib/chef-attribute-validator/checks/looks_like.rb
78
79
  - lib/chef-attribute-validator/checks/max_children.rb
79
80
  - lib/chef-attribute-validator/checks/min_children.rb
81
+ - lib/chef-attribute-validator/checks/proc.rb
80
82
  - lib/chef-attribute-validator/checks/regex.rb
81
83
  - lib/chef-attribute-validator/checks/required.rb
82
84
  - lib/chef-attribute-validator/checks/type.rb
@@ -88,12 +90,24 @@ files:
88
90
  - lib/chef-attribute-validator/wildcard_expander/no_wildcards.rb
89
91
  - test/fixtures/attr_set.rb
90
92
  - test/fixtures/check_child_count.rb
93
+ - test/fixtures/check_enum_array_empty.rb
94
+ - test/fixtures/check_enum_array_mixed.rb
95
+ - test/fixtures/check_enum_array_strings.rb
96
+ - test/fixtures/check_enum_assorted.rb
97
+ - test/fixtures/check_enum_nil.rb
98
+ - test/fixtures/check_enum_string.rb
91
99
  - test/fixtures/check_looks_like_arg_ip.rb
92
100
  - test/fixtures/check_looks_like_arg_regex.rb
93
101
  - test/fixtures/check_looks_like_arg_url.rb
94
102
  - test/fixtures/check_looks_like_arg_your_mom.rb
95
103
  - test/fixtures/check_looks_like_ip.rb
96
104
  - test/fixtures/check_looks_like_url.rb
105
+ - test/fixtures/check_proc_arity0.rb
106
+ - test/fixtures/check_proc_arity1.rb
107
+ - test/fixtures/check_proc_arity2.rb
108
+ - test/fixtures/check_proc_arity3.rb
109
+ - test/fixtures/check_proc_assorted.rb
110
+ - test/fixtures/check_proc_nil.rb
97
111
  - test/fixtures/check_regex_assorted.rb
98
112
  - test/fixtures/check_regex_literal.rb
99
113
  - test/fixtures/check_regex_nil.rb
@@ -115,7 +129,9 @@ files:
115
129
  - test/unit/attr_set_spec.rb
116
130
  - test/unit/attr_set_spec_wildcard.rb
117
131
  - test/unit/check_child_count_spec.rb
132
+ - test/unit/check_enum_spec.rb
118
133
  - test/unit/check_looks_like_spec.rb
134
+ - test/unit/check_proc_spec.rb
119
135
  - test/unit/check_regex_spec.rb
120
136
  - test/unit/check_required_spec.rb
121
137
  - test/unit/check_type_spec.rb
@@ -149,12 +165,24 @@ summary: A Rubygem implementing a rule engine for validating Chef node attribute
149
165
  test_files:
150
166
  - test/fixtures/attr_set.rb
151
167
  - test/fixtures/check_child_count.rb
168
+ - test/fixtures/check_enum_array_empty.rb
169
+ - test/fixtures/check_enum_array_mixed.rb
170
+ - test/fixtures/check_enum_array_strings.rb
171
+ - test/fixtures/check_enum_assorted.rb
172
+ - test/fixtures/check_enum_nil.rb
173
+ - test/fixtures/check_enum_string.rb
152
174
  - test/fixtures/check_looks_like_arg_ip.rb
153
175
  - test/fixtures/check_looks_like_arg_regex.rb
154
176
  - test/fixtures/check_looks_like_arg_url.rb
155
177
  - test/fixtures/check_looks_like_arg_your_mom.rb
156
178
  - test/fixtures/check_looks_like_ip.rb
157
179
  - test/fixtures/check_looks_like_url.rb
180
+ - test/fixtures/check_proc_arity0.rb
181
+ - test/fixtures/check_proc_arity1.rb
182
+ - test/fixtures/check_proc_arity2.rb
183
+ - test/fixtures/check_proc_arity3.rb
184
+ - test/fixtures/check_proc_assorted.rb
185
+ - test/fixtures/check_proc_nil.rb
158
186
  - test/fixtures/check_regex_assorted.rb
159
187
  - test/fixtures/check_regex_literal.rb
160
188
  - test/fixtures/check_regex_nil.rb
@@ -176,7 +204,9 @@ test_files:
176
204
  - test/unit/attr_set_spec.rb
177
205
  - test/unit/attr_set_spec_wildcard.rb
178
206
  - test/unit/check_child_count_spec.rb
207
+ - test/unit/check_enum_spec.rb
179
208
  - test/unit/check_looks_like_spec.rb
209
+ - test/unit/check_proc_spec.rb
180
210
  - test/unit/check_regex_spec.rb
181
211
  - test/unit/check_required_spec.rb
182
212
  - test/unit/check_type_spec.rb