/usr/lib/ruby/vendor_ruby/fog/schema/data_validator.rb is in ruby-fog-core 1.45.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | module Fog
module Schema
# This validates a data object against a Ruby based schema to see
# if they match.
#
# * An object matches the schema if +==+ or +===+ returns +true+
# * Hashes match if all the key's values match the classes given
# in the schema as well. This can be configured in the options
# * Arrays match when every element in the data matches the case
# given in the schema.
#
# The schema and validation are very simple and probably not
# suitable for some cases.
#
# The following classes can be used to check for special behaviour
#
# * Fog::Boolean - value may be +true+ or +false+
# * Fog::Nullable::Boolean - value may be +true+, +false+ or +nil+
# * Fog::Nullable::Integer - value may be an Integer or +nil+
# * Fog::Nullable::String
# * Fog::Nullable::Time
# * Fog::Nullable::Float
# * Fog::Nullable::Hash
# * Fog::Nullable::Array
#
# All the "nullable" objects will pass if the value is of the class
# or if it is +nil+. This allows you to match APIs that may include
# keys when the value is not available in some cases but will
# always be a String. Such as an password that is only displayed
# on the reset action.
#
# The keys for "nullable" resources should always be present but
# original matcher had a bug that allowed these to also appear to
# work as optional keys/values.
#
# If you need the original behaviour, data with a missing key is
# still valid, then you may pass the +:allow_optional_rules+
# option to the #validate method.
#
# That is not recommended because you are describing a schema
# with optional keys in a format that does not support it.
#
# Setting +:allow_extra_keys+ as +true+ allows the data to
# contain keys not declared by the schema and still pass. This
# is useful if new attributes appear in the API in a backwards
# compatible manner and can be ignored.
#
# This is the behaviour you would have seen with +strict+ being
# +false+ in the original test helper.
#
# @example Schema example
# {
# "id" => String,
# "ram" => Integer,
# "disks" => [
# "size" => Float
# ],
# "dns_name" => Fog::Nullable::String,
# "active" => Fog::Boolean,
# "created" => DateTime
# }
#
class DataValidator
# This returns the last message set by the validator
#
# @return [String]
attr_reader :message
def initialize
@message = nil
end
# Checks if the data structure matches the schema passed in and
# returns +true+ if it fits.
#
# @param [Object] data Hash or Array to check
# @param [Object] schema Schema pattern to check against
# @param [Boolean] options
# @option options [Boolean] :allow_extra_keys
# If +true+ does not fail if extra keys are in the data
# that are not in the schema.
# @option options [Boolean] :allow_optional_rules
# If +true+ does not fail if extra keys are in the schema
# that do not match the data. Not recommended!
#
# @return [Boolean] Did the data fit the schema?
def validate(data, schema, options = {})
valid = validate_value(schema, data, options)
unless valid
@message = "#{data.inspect} does not match #{schema.inspect}"
end
valid
end
private
# This contains a slightly modified version of the Hashidator gem
# but unfortunately the gem does not cope with Array schemas.
#
# @see https://github.com/vangberg/hashidator/blob/master/lib/hashidator.rb
#
def validate_value(validator, value, options)
Fog::Logger.write :debug, "[yellow][DEBUG] #{value.inspect} against #{validator.inspect}[/]\n"
case validator
when Array
return false if value.is_a?(Hash)
value.respond_to?(:all?) && value.all? { |x| validate_value(validator[0], x, options) }
when Symbol
value.respond_to? validator
when Hash
return false if value.is_a?(Array)
# When being strict values not specified in the schema are fails
# Validator is empty but values are not
return false if !options[:allow_extra_keys] &&
value.respond_to?(:empty?) &&
!value.empty? &&
validator.empty?
# Validator has rules left but no more values
return false if !options[:allow_optional_rules] &&
value.respond_to?(:empty?) &&
value.empty? &&
!validator.empty?
validator.all? do |key, sub_validator|
Fog::Logger.write :debug, "[blue][DEBUG] #{key.inspect} against #{sub_validator.inspect}[/]\n"
validate_value(sub_validator, value[key], options)
end
else
result = validator == value
result = validator === value unless result
# Repeat unless we have a Boolean already
unless result.is_a?(TrueClass) || result.is_a?(FalseClass)
result = validate_value(result, value, options)
end
if result
Fog::Logger.write :debug, "[green][DEBUG] Validation passed: #{value.inspect} against #{validator.inspect}[/]\n"
else
Fog::Logger.write :debug, "[red][DEBUG] Validation failed: #{value.inspect} against #{validator.inspect}[/]\n"
end
result
end
end
end
end
end
|