chef-attribute-validator 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +20 -0
  3. data/CHANGES +4 -0
  4. data/Gemfile +2 -0
  5. data/LICENSE +27 -0
  6. data/README.md +109 -0
  7. data/Rakefile +27 -0
  8. data/chef-attribute-validator.gemspec +25 -0
  9. data/lib/chef-attribute-validator.rb +52 -0
  10. data/lib/chef-attribute-validator/attribute_set.rb +90 -0
  11. data/lib/chef-attribute-validator/check.rb +56 -0
  12. data/lib/chef-attribute-validator/checks/looks_like.rb +52 -0
  13. data/lib/chef-attribute-validator/checks/max_children.rb +37 -0
  14. data/lib/chef-attribute-validator/checks/min_children.rb +37 -0
  15. data/lib/chef-attribute-validator/checks/regex.rb +31 -0
  16. data/lib/chef-attribute-validator/checks/required.rb +42 -0
  17. data/lib/chef-attribute-validator/checks/type.rb +48 -0
  18. data/lib/chef-attribute-validator/rule.rb +54 -0
  19. data/lib/chef-attribute-validator/version.rb +7 -0
  20. data/lib/chef-attribute-validator/violation.rb +17 -0
  21. data/test/fixtures/attr_set.rb +10 -0
  22. data/test/fixtures/check_child_count.rb +104 -0
  23. data/test/fixtures/check_looks_like_arg_ip.rb +6 -0
  24. data/test/fixtures/check_looks_like_arg_regex.rb +6 -0
  25. data/test/fixtures/check_looks_like_arg_url.rb +6 -0
  26. data/test/fixtures/check_looks_like_arg_your_mom.rb +6 -0
  27. data/test/fixtures/check_looks_like_ip.rb +57 -0
  28. data/test/fixtures/check_looks_like_url.rb +39 -0
  29. data/test/fixtures/check_regex_assorted.rb +42 -0
  30. data/test/fixtures/check_regex_literal.rb +5 -0
  31. data/test/fixtures/check_regex_nil.rb +5 -0
  32. data/test/fixtures/check_regex_object.rb +5 -0
  33. data/test/fixtures/check_regex_string.rb +5 -0
  34. data/test/fixtures/check_required_assorted.rb +82 -0
  35. data/test/fixtures/check_required_false.rb +5 -0
  36. data/test/fixtures/check_required_true.rb +5 -0
  37. data/test/fixtures/check_required_zero.rb +5 -0
  38. data/test/fixtures/check_type.rb +270 -0
  39. data/test/fixtures/rules_empty.rb +2 -0
  40. data/test/fixtures/rules_missing_path.rb +1 -0
  41. data/test/fixtures/rules_no_check.rb +1 -0
  42. data/test/fixtures/rules_type_and_min_children.rb +3 -0
  43. data/test/fixtures/rules_type_check.rb +2 -0
  44. data/test/unit/attr_set_spec.rb +55 -0
  45. data/test/unit/check_child_count_spec.rb +109 -0
  46. data/test/unit/check_looks_like_spec.rb +106 -0
  47. data/test/unit/check_regex_spec.rb +62 -0
  48. data/test/unit/check_required_spec.rb +106 -0
  49. data/test/unit/check_type_spec.rb +191 -0
  50. data/test/unit/rule_parse_spec.rb +93 -0
  51. data/test/unit/spec_helper.rb +18 -0
  52. metadata +170 -0
@@ -0,0 +1,2 @@
1
+ # Empty attributes file
2
+ default['attribute-validator']['rules'] = {}
@@ -0,0 +1 @@
1
+ default['attribute-validator']['rules']['test-missing-path']['enabled'] = true
@@ -0,0 +1 @@
1
+ default['attribute-validator']['rules']['test-no-check-rule']['path'] = '/*'
@@ -0,0 +1,3 @@
1
+ default['attribute-validator']['rules']['test-type-and-min-children-rule']['path'] = '/*'
2
+ default['attribute-validator']['rules']['test-type-and-min-children-rule']['type'] = 'array'
3
+ default['attribute-validator']['rules']['test-type-and-min-children-rule']['min_children'] = 1
@@ -0,0 +1,2 @@
1
+ default['attribute-validator']['rules']['test-type-rule']['path'] = '/*'
2
+ default['attribute-validator']['rules']['test-type-rule']['type'] = 'string'
@@ -0,0 +1,55 @@
1
+ require_relative './spec_helper'
2
+
3
+ describe Chef::Attribute::Validator::AttributeSet do
4
+
5
+ let(:node) { CAVHelper.load_fixture_attributes('attr_set') }
6
+
7
+ describe "non-wildcard, non-array slashpath access" do
8
+ context "when the element exists" do
9
+ it "should be able to run /one" do
10
+ expect { Chef::Attribute::Validator::AttributeSet.new(node, '/one') }.not_to raise_error
11
+ end
12
+ let(:ats) { Chef::Attribute::Validator::AttributeSet.new(node, '/one') }
13
+ it "should be able to find /one" do
14
+ expect(ats.size).to eq 1
15
+ expect(ats.has_key?('/one')).to be_true
16
+ expect(ats['/one']).to eq 1
17
+ end
18
+ end
19
+
20
+ context "when the element does not exist" do
21
+ it "should be able to run /nope" do
22
+ expect { Chef::Attribute::Validator::AttributeSet.new(node, '/nope') }.not_to raise_error
23
+ end
24
+ let(:ats) { Chef::Attribute::Validator::AttributeSet.new(node, '/nope') }
25
+ it "should not be able to find /nope" do
26
+ expect(ats.size).to eq 0
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "non-wildcard, array slashpath access" do
32
+ context "when the element exists" do
33
+ it "should be able to run /cats/1" do
34
+ expect { Chef::Attribute::Validator::AttributeSet.new(node, '/cats/1') }.not_to raise_error
35
+ end
36
+ let(:ats) { Chef::Attribute::Validator::AttributeSet.new(node, '/cats/1') }
37
+ it "should be able to find /cats/1" do
38
+ expect(ats.size).to eq 1
39
+ expect(ats.has_key?('/cats/1')).to be_true
40
+ expect(ats['/cats/1']).to eq 'tabby'
41
+ end
42
+ end
43
+
44
+ context "when the element does not exist" do
45
+ it "should be able to run /cats/23" do
46
+ expect { Chef::Attribute::Validator::AttributeSet.new(node, '/cats/23') }.not_to raise_error
47
+ end
48
+ let(:ats) { Chef::Attribute::Validator::AttributeSet.new(node, '/cats/23') }
49
+ it "should not be able to find /cats/23" do
50
+ expect(ats.size).to eq 0
51
+ end
52
+ end
53
+ end
54
+
55
+ end
@@ -0,0 +1,109 @@
1
+ require_relative './spec_helper'
2
+
3
+ # Verify that the 'type' check works correctly
4
+
5
+
6
+ describe "'min_children' check" do
7
+
8
+ let(:node) { CAVHelper.load_fixture_attributes('check_child_count') }
9
+ let(:av) { Chef::Attribute::Validator.new(node) }
10
+
11
+ it "should be present in the Check registry" do
12
+ expect(Chef::Attribute::Validator::Check.list_check_types).to include('min_children')
13
+ end
14
+
15
+ it "should violate on nil" do
16
+ expect(av.validate_rule('min-nil')).not_to be_empty
17
+ end
18
+
19
+ it "should violate on string" do
20
+ expect(av.validate_rule('min-string')).not_to be_empty
21
+ end
22
+
23
+ context "when examining an array" do
24
+ it "should not violate when min is 0 and array is empty" do
25
+ expect(av.validate_rule('min-array-empty-zero')).to be_empty
26
+ end
27
+
28
+ it "should violate when min is 1 and array is empty" do
29
+ expect(av.validate_rule('min-array-empty-one')).not_to be_empty
30
+ end
31
+
32
+ it "should violate when min is 2 and array is 1" do
33
+ expect(av.validate_rule('min-array-one-two')).not_to be_empty
34
+ end
35
+ end
36
+
37
+ context "when examining a hash" do
38
+ it "should not violate when min is 0 and hash is empty" do
39
+ expect(av.validate_rule('min-hash-empty-zero')).to be_empty
40
+ end
41
+
42
+ it "should violate when min is 1 and hash is empty" do
43
+ expect(av.validate_rule('min-hash-empty-one')).not_to be_empty
44
+ end
45
+
46
+ it "should violate when min is 2 and hash is 1" do
47
+ expect(av.validate_rule('min-hash-one-two')).not_to be_empty
48
+ end
49
+ end
50
+
51
+ end
52
+
53
+ describe "'max_children' check" do
54
+
55
+ let(:node) { CAVHelper.load_fixture_attributes('check_child_count') }
56
+ let(:av) { Chef::Attribute::Validator.new(node) }
57
+
58
+ it "should be present in the Check registry" do
59
+ expect(Chef::Attribute::Validator::Check.list_check_types).to include('max_children')
60
+ end
61
+
62
+ it "should violate on nil" do
63
+ expect(av.validate_rule('max-nil')).not_to be_empty
64
+ end
65
+
66
+ it "should violate on string" do
67
+ expect(av.validate_rule('max-string')).not_to be_empty
68
+ end
69
+
70
+ context "when examining an array" do
71
+ it "should not violate when max is 0 and array is empty" do
72
+ expect(av.validate_rule('max-array-empty-zero')).to be_empty
73
+ end
74
+
75
+ it "should violate when max is 0 and array is 1" do
76
+ expect(av.validate_rule('max-array-zero-one')).not_to be_empty
77
+ end
78
+
79
+ it "should violate when max is 1 and array is 2" do
80
+ expect(av.validate_rule('max-array-one-two')).not_to be_empty
81
+ end
82
+
83
+ it "should not violate when max is 2 and array is 2" do
84
+ expect(av.validate_rule('max-array-two-two')).to be_empty
85
+ end
86
+
87
+ end
88
+
89
+ context "when examining a hash" do
90
+ it "should not violate when max is 0 and hash is empty" do
91
+ expect(av.validate_rule('max-hash-empty-zero')).to be_empty
92
+ end
93
+
94
+ it "should violate when max is 0 and hash is one" do
95
+ expect(av.validate_rule('max-hash-zero-one')).not_to be_empty
96
+ end
97
+
98
+ it "should violate when max is 1 and hash is 2" do
99
+ expect(av.validate_rule('max-hash-one-two')).not_to be_empty
100
+ end
101
+
102
+ it "should not violate when max is 2 and hash is 2" do
103
+ expect(av.validate_rule('max-hash-two-two')).to be_empty
104
+ end
105
+
106
+ end
107
+
108
+
109
+ end
@@ -0,0 +1,106 @@
1
+ require_relative './spec_helper'
2
+
3
+ # Verify that the 'looks_like' check works correctly
4
+
5
+
6
+ describe "'looks_like' check" do
7
+
8
+ describe "check registry" do
9
+ it "should be present in the Check registry" do
10
+ expect(Chef::Attribute::Validator::Check.list_check_types).to include('looks_like')
11
+ end
12
+ end
13
+
14
+ describe "check_arg checks" do
15
+ it "should accept 'ip'" do
16
+ node = CAVHelper.load_fixture_attributes('check_looks_like_arg_ip')
17
+ expect { Chef::Attribute::Validator.new(node) }.not_to raise_error
18
+ end
19
+ it "should accept 'url'" do
20
+ node = CAVHelper.load_fixture_attributes('check_looks_like_arg_url')
21
+ expect { Chef::Attribute::Validator.new(node) }.not_to raise_error
22
+ end
23
+ it "should reject 'your mom'" do
24
+ node = CAVHelper.load_fixture_attributes('check_looks_like_arg_your_mom')
25
+ expect { Chef::Attribute::Validator.new(node) }.to raise_error
26
+ end
27
+ it "should reject a regex" do
28
+ node = CAVHelper.load_fixture_attributes('check_looks_like_arg_regex')
29
+ expect { Chef::Attribute::Validator.new(node) }.to raise_error
30
+ end
31
+ end
32
+
33
+ context "when the mode is 'ip'" do
34
+ let(:node) { CAVHelper.load_fixture_attributes('check_looks_like_ip') }
35
+ let(:av) { Chef::Attribute::Validator.new(node) }
36
+
37
+ it "should not violate on missing" do
38
+ expect(av.validate_rule('ip-missing')).to be_empty
39
+ end
40
+
41
+ it "should not violate on nil" do
42
+ expect(av.validate_rule('ip-nil')).to be_empty
43
+ end
44
+
45
+ it "should violate on 1234.123.1.1" do
46
+ expect(av.validate_rule('ip-malformed')).not_to be_empty
47
+ end
48
+
49
+ it "should violate on 300.300.300.1" do
50
+ expect(av.validate_rule('ip-deranged')).not_to be_empty
51
+ end
52
+
53
+ it "should violate on 123.123.123" do
54
+ expect(av.validate_rule('ip-3not4')).not_to be_empty
55
+ end
56
+
57
+ it "should not violate on 1.1.1.1" do
58
+ expect(av.validate_rule('ip-allones')).to be_empty
59
+ end
60
+
61
+ it "should not violate on 1.1.1.1/24" do
62
+ expect(av.validate_rule('ip-slash24')).to be_empty
63
+ end
64
+
65
+ it "should not violate on 255.255.255.255" do
66
+ expect(av.validate_rule('ip-merryxmas')).to be_empty
67
+ end
68
+
69
+ it "should not violate on ::" do
70
+ expect(av.validate_rule('ip-emptyv6')).to be_empty
71
+ end
72
+ end
73
+
74
+ context "when the mode is 'url'" do
75
+ let(:node) { CAVHelper.load_fixture_attributes('check_looks_like_url') }
76
+ let(:av) { Chef::Attribute::Validator.new(node) }
77
+
78
+ it "should not violate on missing" do
79
+ expect(av.validate_rule('url-missing')).to be_empty
80
+ end
81
+
82
+ it "should not violate on nil" do
83
+ expect(av.validate_rule('url-nil')).to be_empty
84
+ end
85
+
86
+ it "should not violate on 'http://wwwwwwww.jodi.org'" do
87
+ expect(av.validate_rule('url-http-basic')).to be_empty
88
+ end
89
+
90
+ it "should not violate on 'http://example.com/'" do
91
+ expect(av.validate_rule('url-http-trailing-slash')).to be_empty
92
+ end
93
+
94
+ it "should not violate on 'http://example.com:8080/'" do
95
+ expect(av.validate_rule('url-http-port')).to be_empty
96
+ end
97
+
98
+ it "should not violate on 'http://localhost'" do
99
+ expect(av.validate_rule('url-http-localhost')).to be_empty
100
+ end
101
+
102
+ end
103
+
104
+
105
+
106
+ end
@@ -0,0 +1,62 @@
1
+ require_relative './spec_helper'
2
+
3
+ # Verify that the 'regex' check works correctly
4
+
5
+
6
+ describe "'regex' check" do
7
+
8
+ describe "check registry" do
9
+ it "should be present in the Check registry" do
10
+ expect(Chef::Attribute::Validator::Check.list_check_types).to include('regex')
11
+ end
12
+ end
13
+
14
+ describe "check_arg checks" do
15
+ it "should accept a // literal regex" do
16
+ node = CAVHelper.load_fixture_attributes('check_regex_literal')
17
+ expect { Chef::Attribute::Validator.new(node) }.not_to raise_error
18
+ end
19
+ it "should accept a Regexp object" do
20
+ node = CAVHelper.load_fixture_attributes('check_regex_object')
21
+ expect { Chef::Attribute::Validator.new(node) }.not_to raise_error
22
+ end
23
+ it "should reject a string" do
24
+ node = CAVHelper.load_fixture_attributes('check_regex_string')
25
+ expect { Chef::Attribute::Validator.new(node) }.to raise_error
26
+ end
27
+ it "should reject a nil regex" do
28
+ node = CAVHelper.load_fixture_attributes('check_regex_nil')
29
+ expect { Chef::Attribute::Validator.new(node) }.to raise_error
30
+ end
31
+ end
32
+
33
+ describe "assorted regexes" do
34
+ let(:node) { CAVHelper.load_fixture_attributes('check_regex_assorted') }
35
+ let(:av) { Chef::Attribute::Validator.new(node) }
36
+
37
+ it "/^$/ should not violate on an empty string" do
38
+ expect(av.validate_rule('empty-empty')).to be_empty
39
+ end
40
+
41
+ it "/foo/ should not violate on foo" do
42
+ expect(av.validate_rule('foo-foo')).to be_empty
43
+ end
44
+
45
+ it "/foo/ should not violate on food" do
46
+ expect(av.validate_rule('foo-food')).to be_empty
47
+ end
48
+
49
+ it "/foo/ should violate on victuals" do
50
+ expect(av.validate_rule('foo-victuals')).not_to be_empty
51
+ end
52
+
53
+ it "/^(?!foo)/ should not violate on bar" do
54
+ expect(av.validate_rule('not-foo-bar')).to be_empty
55
+ end
56
+
57
+ it "/^(?!foo)/ should violate on foo" do
58
+ expect(av.validate_rule('not-foo-foo')).not_to be_empty
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,106 @@
1
+ require_relative './spec_helper'
2
+
3
+ # Verify that the 'required' check works correctly
4
+
5
+ describe "'required' check" do
6
+
7
+ describe "check registry" do
8
+ it "should be present in the Check registry" do
9
+ expect(Chef::Attribute::Validator::Check.list_check_types).to include('required')
10
+ end
11
+ end
12
+
13
+ describe "check_arg checks" do
14
+ it "should accept true" do
15
+ node = CAVHelper.load_fixture_attributes('check_required_true')
16
+ expect { Chef::Attribute::Validator.new(node) }.not_to raise_error
17
+ end
18
+ it "should accept false" do
19
+ node = CAVHelper.load_fixture_attributes('check_required_false')
20
+ expect { Chef::Attribute::Validator.new(node) }.not_to raise_error
21
+ end
22
+ it "should reject 0" do
23
+ node = CAVHelper.load_fixture_attributes('check_required_zero')
24
+ expect { Chef::Attribute::Validator.new(node) }.to raise_error
25
+ end
26
+ end
27
+
28
+ context "when required, but the attribute is missing" do
29
+ let(:node) { CAVHelper.load_fixture_attributes('check_required_assorted') }
30
+ let(:av) { Chef::Attribute::Validator.new(node) }
31
+
32
+ it "should violate when the attribute is missing, shallow" do
33
+ expect(av.validate_rule('missing-shallow')).not_to be_empty
34
+ end
35
+
36
+ it "should violate when the attribute is missing, deep" do
37
+ expect(av.validate_rule('missing-deep')).not_to be_empty
38
+ end
39
+ end
40
+
41
+ context "when required, but the value is missing" do
42
+ let(:node) { CAVHelper.load_fixture_attributes('check_required_assorted') }
43
+ let(:av) { Chef::Attribute::Validator.new(node) }
44
+
45
+ it "should violate when the value is nil" do
46
+ expect(av.validate_rule('value-nil')).not_to be_empty
47
+ end
48
+
49
+ it "should violate when the value is an empty string" do
50
+ expect(av.validate_rule('value-empty-string')).not_to be_empty
51
+ end
52
+
53
+ it "should violate when the value is an empty array" do
54
+ expect(av.validate_rule('value-empty-array')).not_to be_empty
55
+ end
56
+
57
+ it "should violate when the value is an empty hash" do
58
+ expect(av.validate_rule('value-empty-hash')).not_to be_empty
59
+ end
60
+ end
61
+
62
+ context "when required, and a value is present" do
63
+ let(:node) { CAVHelper.load_fixture_attributes('check_required_assorted') }
64
+ let(:av) { Chef::Attribute::Validator.new(node) }
65
+
66
+ it "should not violate when the value is a string " do
67
+ expect(av.validate_rule('value-present-string')).to be_empty
68
+ end
69
+
70
+ it "should not violate when the value is false " do
71
+ expect(av.validate_rule('value-present-false')).to be_empty
72
+ end
73
+
74
+ it "should not violate when the value is zero " do
75
+ expect(av.validate_rule('value-present-zero')).to be_empty
76
+ end
77
+
78
+ it "should not violate when the value is a non-empty array " do
79
+ expect(av.validate_rule('value-present-array')).to be_empty
80
+ end
81
+
82
+ it "should not violate when the value is a non-empty hash" do
83
+ expect(av.validate_rule('value-present-hash')).to be_empty
84
+ end
85
+ end
86
+
87
+ context "when not required, but the value is present" do
88
+ let(:node) { CAVHelper.load_fixture_attributes('check_required_assorted') }
89
+ let(:av) { Chef::Attribute::Validator.new(node) }
90
+
91
+ it "should not violate when the value is a string" do
92
+ expect(av.validate_rule('optional-present-string')).to be_empty
93
+ end
94
+ end
95
+
96
+ context "when not required, but the attribute is missing" do
97
+ let(:node) { CAVHelper.load_fixture_attributes('check_required_assorted') }
98
+ let(:av) { Chef::Attribute::Validator.new(node) }
99
+
100
+ it "should not violate when the attribute is missing" do
101
+ expect(av.validate_rule('optional-missing')).to be_empty
102
+ end
103
+ end
104
+
105
+
106
+ end