chef-attribute-validator 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +20 -0
- data/CHANGES +4 -0
- data/Gemfile +2 -0
- data/LICENSE +27 -0
- data/README.md +109 -0
- data/Rakefile +27 -0
- data/chef-attribute-validator.gemspec +25 -0
- data/lib/chef-attribute-validator.rb +52 -0
- data/lib/chef-attribute-validator/attribute_set.rb +90 -0
- data/lib/chef-attribute-validator/check.rb +56 -0
- data/lib/chef-attribute-validator/checks/looks_like.rb +52 -0
- data/lib/chef-attribute-validator/checks/max_children.rb +37 -0
- data/lib/chef-attribute-validator/checks/min_children.rb +37 -0
- data/lib/chef-attribute-validator/checks/regex.rb +31 -0
- data/lib/chef-attribute-validator/checks/required.rb +42 -0
- data/lib/chef-attribute-validator/checks/type.rb +48 -0
- data/lib/chef-attribute-validator/rule.rb +54 -0
- data/lib/chef-attribute-validator/version.rb +7 -0
- data/lib/chef-attribute-validator/violation.rb +17 -0
- data/test/fixtures/attr_set.rb +10 -0
- data/test/fixtures/check_child_count.rb +104 -0
- data/test/fixtures/check_looks_like_arg_ip.rb +6 -0
- data/test/fixtures/check_looks_like_arg_regex.rb +6 -0
- data/test/fixtures/check_looks_like_arg_url.rb +6 -0
- data/test/fixtures/check_looks_like_arg_your_mom.rb +6 -0
- data/test/fixtures/check_looks_like_ip.rb +57 -0
- data/test/fixtures/check_looks_like_url.rb +39 -0
- data/test/fixtures/check_regex_assorted.rb +42 -0
- data/test/fixtures/check_regex_literal.rb +5 -0
- data/test/fixtures/check_regex_nil.rb +5 -0
- data/test/fixtures/check_regex_object.rb +5 -0
- data/test/fixtures/check_regex_string.rb +5 -0
- data/test/fixtures/check_required_assorted.rb +82 -0
- data/test/fixtures/check_required_false.rb +5 -0
- data/test/fixtures/check_required_true.rb +5 -0
- data/test/fixtures/check_required_zero.rb +5 -0
- data/test/fixtures/check_type.rb +270 -0
- data/test/fixtures/rules_empty.rb +2 -0
- data/test/fixtures/rules_missing_path.rb +1 -0
- data/test/fixtures/rules_no_check.rb +1 -0
- data/test/fixtures/rules_type_and_min_children.rb +3 -0
- data/test/fixtures/rules_type_check.rb +2 -0
- data/test/unit/attr_set_spec.rb +55 -0
- data/test/unit/check_child_count_spec.rb +109 -0
- data/test/unit/check_looks_like_spec.rb +106 -0
- data/test/unit/check_regex_spec.rb +62 -0
- data/test/unit/check_required_spec.rb +106 -0
- data/test/unit/check_type_spec.rb +191 -0
- data/test/unit/rule_parse_spec.rb +93 -0
- data/test/unit/spec_helper.rb +18 -0
- metadata +170 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
OGU5Y2Y2ZGFjYWIwNjBjMGVhODFiMTMxYWY0NzY1NzcyMWJlMjk0ZQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
M2RmYmFjNTFlYTRjZGIyMTY4YTUwNjZmNmIwYTlhNTZkNzI3YTJlOQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NzM4NjBlNmY1MzdhNTBhNDAyNTc1YmVhMTdlMjExMTdkN2ZlZGNmMGIzZWJm
|
10
|
+
YmE0NmJkZjhhYzliOTY2ZTI3YzE1OTgyMWQ1NzA3N2NjYzYyNTdiNmRmYTZk
|
11
|
+
NDYwZmMzOGM5OWViNWVmYzJkNTZlMDM5MjZmZTE2MzQxYWExMTg=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZWQ4NjdiM2Y3Nzk5NGU1NGZlMDdlODBhMTg5ZDAwOWJiMGE2ZTBhMjQ4MGUy
|
14
|
+
YzA1MGJjNzZiMDlhYzdiZTQ5MTljODRkMjNmMGFmZWE3ZDZlYWJhZjQ0NWQ5
|
15
|
+
YTc3ZTcyZTY0YTVkYzQ2Zjk4OWIzZjQwYmRmYjk3NWU2NjU5MDk=
|
data/.gitignore
ADDED
data/CHANGES
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
Copyright (c) 2013, Clinton Wolfe
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
* Redistributions of source code must retain the above copyright notice, this
|
8
|
+
list of conditions and the following disclaimer.
|
9
|
+
|
10
|
+
* Redistributions in binary form must reproduce the above copyright notice, this
|
11
|
+
list of conditions and the following disclaimer in the documentation and/or
|
12
|
+
other materials provided with the distribution.
|
13
|
+
|
14
|
+
* Neither the name of 'chef-attribute-validator' nor the names of its
|
15
|
+
contributors may be used to endorse or promote products derived from
|
16
|
+
this software without specific prior written permission.
|
17
|
+
|
18
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
19
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
20
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
22
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
23
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
24
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
25
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
26
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
27
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
# Chef::Attribute::Validator
|
2
|
+
|
3
|
+
Define, enforce, and handle violations of validation rules for Chef node
|
4
|
+
attributes. The rule definitions are themselves node attributes. This
|
5
|
+
gem provides the validation engine, and can be used outside of a
|
6
|
+
convergence run; a cookbook (attribute-validator) is planned to perform
|
7
|
+
validation during a chef run, at compile or converge time.
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
### Define Rules
|
12
|
+
|
13
|
+
Define rules by creating attributes that specify checks to make on node
|
14
|
+
attributes that match a given path. By default the library looks for rules
|
15
|
+
under node['attribute-validator']['rules'], but you can override that.
|
16
|
+
|
17
|
+
See Defining Validation Rules.
|
18
|
+
|
19
|
+
### From Within a Chef Recipe
|
20
|
+
|
21
|
+
To scan for violations of all rules, do:
|
22
|
+
|
23
|
+
require 'chef-attribute-validator'
|
24
|
+
violations = Chef::Attribute::Validator.new(node).validate_all
|
25
|
+
|
26
|
+
You can also apply one rule, or rules that match a regex:
|
27
|
+
|
28
|
+
violations = Chef::Attribute::Validator.new(node).validate_rule('rulename')
|
29
|
+
violations = Chef::Attribute::Validator.new(node).validate_matching(/matchme/)
|
30
|
+
|
31
|
+
The return value from each is an array, possibly empty. Each array element is a simple object, with accessors:
|
32
|
+
|
33
|
+
rule_name (string)
|
34
|
+
path (in slash format, see REFERENCING ATTRIBUTES)
|
35
|
+
message
|
36
|
+
|
37
|
+
A single rule may have many violations.
|
38
|
+
|
39
|
+
## Defining Validation Rules
|
40
|
+
|
41
|
+
To define validation rules, create attributes under
|
42
|
+
|
43
|
+
default['attribute-validator']['rules'][<rulename>]...
|
44
|
+
|
45
|
+
Each rule gets a unique name. Each entry is hash structure with the following keys:
|
46
|
+
|
47
|
+
path - Required. Slash formatted path of the attributes to check.
|
48
|
+
enabled - Optional boolean, default true. Set to false to knock out rule.
|
49
|
+
|
50
|
+
The remaining entries describe criteria to enforce on the value of the attribute(s)
|
51
|
+
referenced by 'path'. You may list zero or more.
|
52
|
+
|
53
|
+
type - Checks type of value. One of 'string', 'number', 'boolean', 'hash', 'array'.
|
54
|
+
min_children - Integer. Fails for all but Hash and Array. For Hash and Array, minimum number of elements to be considered valid.
|
55
|
+
max_children - Integer. Fails for all but Hash and Array. For Hash and Array, maximum number of elements to be considered valid.
|
56
|
+
regex - Regexp. Applies given regex to the value. Ignored for Hash and Array. See looks_like for a selection of canned regexen.
|
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
|
+
looks_like - String, one of 'url', 'ip'. Applies canned regexes (or more sophisticated matchers).
|
59
|
+
|
60
|
+
## Referencing Attributes
|
61
|
+
|
62
|
+
Attribute locations are described using a syntax similar to shell globs.
|
63
|
+
|
64
|
+
Given:
|
65
|
+
|
66
|
+
/foo - Matches node['foo']
|
67
|
+
/foo/bar - Matches node['foo']['bar']
|
68
|
+
|
69
|
+
## Bugs, Limitations and Roadmap
|
70
|
+
|
71
|
+
#### Wildcard syntax not yet supported
|
72
|
+
|
73
|
+
I'd like to have at least this:
|
74
|
+
|
75
|
+
/foo/* - Matches node['foo']['bar'], but not node['foo'] or node['foo']['bar']['baz']
|
76
|
+
/foo/c* - Matches node['foo']['car'], but not node['foo']['bar']
|
77
|
+
/foo/?ar - Matches node['foo']['bar'] and node['foo']['bar'] but not node['foo']['bleh']
|
78
|
+
|
79
|
+
Possibly eventually support for **, [<charclass>], or {<alternatives>}.
|
80
|
+
|
81
|
+
#### Companion cookbook
|
82
|
+
|
83
|
+
Simple cookbook named 'attribute-validator' that loads the gem and provides recipes for compile-time and convergence-time violation checking.
|
84
|
+
|
85
|
+
### Lame Exceptions
|
86
|
+
|
87
|
+
No real exception class, just raising a bare string exception, which could certainly be improved upon.
|
88
|
+
|
89
|
+
### Planned checks:
|
90
|
+
|
91
|
+
looks_like/hostname
|
92
|
+
looks_like/email
|
93
|
+
name_regex - Regexp. Applies given regex to the last element in the attribute path ('basename', if you will)
|
94
|
+
present - 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.
|
95
|
+
|
96
|
+
#### Probably Slow
|
97
|
+
|
98
|
+
|
99
|
+
## Author
|
100
|
+
|
101
|
+
Clinton Wolfe
|
102
|
+
|
103
|
+
## Contributing
|
104
|
+
|
105
|
+
1. Fork it (https://github.com/clintoncwolfe/chef-attribute-validator)
|
106
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
107
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
108
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
109
|
+
5. Create new Pull Request at (https://github.com/clintoncwolfe/chef-attribute-validator)
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*-ruby-*-
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
#require 'rspec/core/rake_task'
|
5
|
+
require "bundler/gem_tasks"
|
6
|
+
|
7
|
+
desc "Runs all development tests"
|
8
|
+
task :test
|
9
|
+
|
10
|
+
|
11
|
+
task :test => [:syntax]
|
12
|
+
desc "Checks ruby files for syntax errors"
|
13
|
+
task :syntax do |t|
|
14
|
+
Dir.glob('**/*.rb').each do |f|
|
15
|
+
system("/bin/echo -n '#{f}: '; ruby -c #{f}")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
task :test => [:unit]
|
20
|
+
desc "Runs unit tests"
|
21
|
+
#RSpec::Core::RakeTask.new(:unit) do |t|
|
22
|
+
# t.pattern = 'test/unit/**/*_spec.rb'
|
23
|
+
# t.rspec_opts = "-fd"
|
24
|
+
#end
|
25
|
+
|
26
|
+
|
27
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8 # -*-ruby-*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'chef-attribute-validator/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "chef-attribute-validator"
|
8
|
+
spec.version = Chef::Attribute::Validator::VERSION
|
9
|
+
spec.authors = ["Clinton Wolfe"]
|
10
|
+
spec.email = ["clinton@omniti.com"]
|
11
|
+
spec.description = %q{Define, enforce, and handle violations of validation rules for Chef node attributes. This gem provides the validation engine, and can be used outside of a convergence run; a cookbook (attribute-validator) is availabel to perform validation during a chef run, at compile or converge time.}
|
12
|
+
spec.summary = %q{A Rubygem implementing a rule engine for validating Chef node attributes.}
|
13
|
+
spec.homepage = "https://github.com/clintoncwolfe/chef-attribute-validator"
|
14
|
+
spec.license = "BSD (3-clause)"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
|
24
|
+
spec.add_runtime_dependency "chef", "~> 11.6.0" # TODO: test with older chefs
|
25
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "chef-attribute-validator/version"
|
2
|
+
require "chef-attribute-validator/violation"
|
3
|
+
require "chef-attribute-validator/rule"
|
4
|
+
require "chef-attribute-validator/attribute_set"
|
5
|
+
|
6
|
+
class Chef
|
7
|
+
class Attribute
|
8
|
+
class Validator
|
9
|
+
|
10
|
+
attr_accessor :node
|
11
|
+
attr_accessor :rules
|
12
|
+
|
13
|
+
def initialize(a_node)
|
14
|
+
@node = a_node
|
15
|
+
populate_rules
|
16
|
+
end
|
17
|
+
|
18
|
+
def validate_all
|
19
|
+
violations = []
|
20
|
+
rules.each do |rulename, rule|
|
21
|
+
violations += rule.apply(node)
|
22
|
+
end
|
23
|
+
violations
|
24
|
+
end
|
25
|
+
|
26
|
+
def validate_rule(rulename)
|
27
|
+
unless rules.has_key?(rulename)
|
28
|
+
raise "No such attribute validation rule named '#{rulename}' - have rules: #{rules.keys.sort.join(',')}"
|
29
|
+
end
|
30
|
+
rules[rulename].apply(node)
|
31
|
+
end
|
32
|
+
|
33
|
+
def validate_matching(rule_regex)
|
34
|
+
violations = []
|
35
|
+
rules.select { |rn,r| rule_regex.match(rn) }.each do |rulename, rule|
|
36
|
+
violations += rule.apply(node)
|
37
|
+
end
|
38
|
+
violations
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def populate_rules
|
44
|
+
@rules = {}
|
45
|
+
node['attribute-validator']['rules'].each do |rulename, ruledef|
|
46
|
+
rules[rulename] = Chef::Attribute::Validator::Rule.new(rulename, ruledef)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
class Chef
|
5
|
+
class Attribute
|
6
|
+
class Validator
|
7
|
+
|
8
|
+
class AttributeSet
|
9
|
+
attr_accessor :guts
|
10
|
+
attr_accessor :path
|
11
|
+
attr_accessor :node
|
12
|
+
|
13
|
+
extend Forwardable
|
14
|
+
|
15
|
+
def_delegators :@guts, :size, :each, :empty?, :has_key?, :[], :keys, :select, :reject
|
16
|
+
|
17
|
+
def initialize(a_node, a_path)
|
18
|
+
@guts = {}
|
19
|
+
@path = a_path
|
20
|
+
@node = a_node
|
21
|
+
|
22
|
+
embowel
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def embowel
|
28
|
+
# Split on /
|
29
|
+
steps = path.split('/')
|
30
|
+
|
31
|
+
# Since we begin with /, the first element is ""
|
32
|
+
if steps[0] == "" then steps.shift end
|
33
|
+
|
34
|
+
# Promote integer strings to integers
|
35
|
+
steps.map! { |s| s.match(/^\d+$/) ? s.to_i : s }
|
36
|
+
|
37
|
+
# TODO: some ckine of wildcard expansion
|
38
|
+
all_steps = [ steps ]
|
39
|
+
|
40
|
+
all_steps.each do |these_steps|
|
41
|
+
if path_exists_by_steps?(these_steps) then
|
42
|
+
guts['/' + these_steps.join('/')] = fetch_val_by_steps(these_steps)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def path_exists_by_steps? (the_steps)
|
48
|
+
nv = node
|
49
|
+
steps = the_steps.dup
|
50
|
+
while steps.size > 0
|
51
|
+
step = steps.shift
|
52
|
+
|
53
|
+
# binding.pry
|
54
|
+
if nv.kind_of?(Chef::Node::ImmutableArray) then
|
55
|
+
# TODO: what if the step isn't an int?
|
56
|
+
|
57
|
+
if nv.size > step then
|
58
|
+
nv = nv[step]
|
59
|
+
else
|
60
|
+
# Array not long enough
|
61
|
+
return false
|
62
|
+
end
|
63
|
+
|
64
|
+
elsif nv.respond_to?(:has_key?) then
|
65
|
+
if nv.has_key?(step) then
|
66
|
+
nv = nv[step]
|
67
|
+
else
|
68
|
+
# No such key
|
69
|
+
return false
|
70
|
+
end
|
71
|
+
else
|
72
|
+
# Must be a scalar?
|
73
|
+
return false
|
74
|
+
end
|
75
|
+
end
|
76
|
+
return true
|
77
|
+
end
|
78
|
+
|
79
|
+
def fetch_val_by_steps(the_steps)
|
80
|
+
nv = node
|
81
|
+
steps = the_steps.dup
|
82
|
+
while steps.size > 0
|
83
|
+
nv = nv[steps.shift]
|
84
|
+
end
|
85
|
+
nv
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
class Chef
|
2
|
+
class Attribute
|
3
|
+
class Validator
|
4
|
+
class Check
|
5
|
+
attr_accessor :path_spec
|
6
|
+
attr_accessor :check_arg
|
7
|
+
attr_accessor :rule_name
|
8
|
+
|
9
|
+
def initialize(a_rule, a_check_arg)
|
10
|
+
@path_spec = a_rule.path
|
11
|
+
@rule_name = a_rule.name
|
12
|
+
@check_arg = a_check_arg
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.make(check_name, a_rule, a_check_arg)
|
16
|
+
unless @@check_classes.has_key?(check_name)
|
17
|
+
raise "Unrecognized option or check type '#{check_name}' for attribute validation rule '#{a_rule.name}'"
|
18
|
+
end
|
19
|
+
checker = @@check_classes[check_name].new(a_rule, a_check_arg)
|
20
|
+
checker.validate_check_arg
|
21
|
+
checker
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.list_check_types
|
25
|
+
@@check_classes.keys
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
def self.register_check (check_name, klass)
|
31
|
+
@@check_classes ||= {}
|
32
|
+
@@check_classes[check_name] = klass
|
33
|
+
end
|
34
|
+
|
35
|
+
def val_scalar?(val)
|
36
|
+
[
|
37
|
+
Float,
|
38
|
+
Integer,
|
39
|
+
NilClass,
|
40
|
+
TrueClass,
|
41
|
+
FalseClass,
|
42
|
+
String,
|
43
|
+
].any? { |k| val.kind_of?(k) }
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'checks', '*.rb')).each do |check_implementation|
|
55
|
+
require check_implementation
|
56
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
|
2
|
+
require 'ipaddr'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
class Chef
|
6
|
+
class Attribute
|
7
|
+
class Validator
|
8
|
+
class Check
|
9
|
+
class LooksLike < Check
|
10
|
+
|
11
|
+
register_check('looks_like', LooksLike)
|
12
|
+
|
13
|
+
def validate_check_arg
|
14
|
+
expected = [
|
15
|
+
'ip',
|
16
|
+
'url',
|
17
|
+
]
|
18
|
+
|
19
|
+
unless expected.include?(check_arg)
|
20
|
+
raise "Bad 'looks_like' check argument '#{check_arg}' for rule '#{rule_name}' - expected one of #{expected.join(',')}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def check(attrset)
|
25
|
+
violations = []
|
26
|
+
attrset.each do |path, value|
|
27
|
+
if val_scalar?(value) then
|
28
|
+
next if value.nil?
|
29
|
+
case check_arg
|
30
|
+
when 'ip'
|
31
|
+
begin
|
32
|
+
IPAddr.new(value)
|
33
|
+
rescue
|
34
|
+
violations.push Chef::Attribute::Validator::Violation.new(rule_name, path, "Value '#{value}' does not look like an IP address")
|
35
|
+
end
|
36
|
+
when 'url'
|
37
|
+
begin
|
38
|
+
URI(value)
|
39
|
+
rescue
|
40
|
+
violations.push Chef::Attribute::Validator::Violation.new(rule_name, path, "Value '#{value}' does not look like a URL")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
violations
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|