vcloud-core 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +6 -0
- data/lib/vcloud/core.rb +2 -0
- data/lib/vcloud/core/config_loader.rb +26 -0
- data/lib/vcloud/core/config_validator.rb +208 -0
- data/lib/vcloud/core/version.rb +1 -1
- data/spec/vcloud/core/config_loader_spec.rb +102 -0
- data/spec/vcloud/core/config_validator_spec.rb +572 -0
- data/spec/vcloud/{data → core/data}/basic_preamble_test.erb +0 -0
- data/spec/vcloud/{data → core/data}/basic_preamble_test.erb.OUT +0 -0
- data/spec/vcloud/core/data/working.json +21 -0
- data/spec/vcloud/core/data/working.yaml +22 -0
- data/spec/vcloud/core/data/working_with_defaults.yaml +25 -0
- data/spec/vcloud/core/vm_spec.rb +1 -1
- metadata +19 -7
data/CHANGELOG.md
CHANGED
data/lib/vcloud/core.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Vcloud
|
2
|
+
module Core
|
3
|
+
class ConfigLoader
|
4
|
+
|
5
|
+
def load_config(config_file, schema = nil)
|
6
|
+
input_config = YAML::load(File.open(config_file))
|
7
|
+
|
8
|
+
# There is no way in YAML or Ruby to symbolize keys in a hash
|
9
|
+
json_string = JSON.generate(input_config)
|
10
|
+
config = JSON.parse(json_string, :symbolize_names => true)
|
11
|
+
|
12
|
+
if schema
|
13
|
+
validation = Core::ConfigValidator.validate(:base, config, schema)
|
14
|
+
unless validation.valid?
|
15
|
+
validation.errors.each do |error|
|
16
|
+
Vcloud::Core.logger.fatal(error)
|
17
|
+
end
|
18
|
+
raise("Supplied configuration does not match supplied schema")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
config
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
|
3
|
+
module Vcloud
|
4
|
+
module Core
|
5
|
+
class ConfigValidator
|
6
|
+
|
7
|
+
attr_reader :key, :data, :schema, :type, :errors
|
8
|
+
|
9
|
+
VALID_ALPHABETICAL_VALUES_FOR_IP_RANGE = %w(Any external internal)
|
10
|
+
|
11
|
+
def initialize(key, data, schema)
|
12
|
+
raise "Nil schema" unless schema
|
13
|
+
raise "Invalid schema" unless schema.key?(:type)
|
14
|
+
@type = schema[:type].to_s.downcase
|
15
|
+
@errors = []
|
16
|
+
@data = data
|
17
|
+
@schema = schema
|
18
|
+
@key = key
|
19
|
+
validate
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid?
|
23
|
+
@errors.empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.validate(key, data, schema)
|
27
|
+
new(key, data, schema)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def validate
|
33
|
+
self.send("validate_#{type}".to_sym)
|
34
|
+
end
|
35
|
+
|
36
|
+
def validate_string
|
37
|
+
unless @data.is_a? String
|
38
|
+
errors << "#{key}: #{@data} is not a string"
|
39
|
+
return
|
40
|
+
end
|
41
|
+
return unless check_emptyness_ok
|
42
|
+
return unless check_matcher_matches
|
43
|
+
end
|
44
|
+
|
45
|
+
def validate_string_or_number
|
46
|
+
unless data.is_a?(String) || data.is_a?(Numeric)
|
47
|
+
@errors << "#{key}: #{@data} is not a string_or_number"
|
48
|
+
return
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def validate_ip_address
|
53
|
+
unless data.is_a?(String)
|
54
|
+
@errors << "#{key}: #{@data} is not a valid ip_address"
|
55
|
+
return
|
56
|
+
end
|
57
|
+
@errors << "#{key}: #{@data} is not a valid ip_address" unless valid_ip_address?(data)
|
58
|
+
end
|
59
|
+
|
60
|
+
def validate_ip_address_range
|
61
|
+
unless data.is_a?(String)
|
62
|
+
@errors << "#{key}: #{@data} is not a valid IP address range. Valid values can be IP address, CIDR, IP range, 'Any','internal' and 'external'."
|
63
|
+
return
|
64
|
+
end
|
65
|
+
valid = valid_cidr_or_ip_address? || valid_alphabetical_ip_range? || valid_ip_range?
|
66
|
+
@errors << "#{key}: #{@data} is not a valid IP address range. Valid values can be IP address, CIDR, IP range, 'Any','internal' and 'external'." unless valid
|
67
|
+
end
|
68
|
+
|
69
|
+
def valid_cidr_or_ip_address?
|
70
|
+
begin
|
71
|
+
ip = IPAddr.new(data)
|
72
|
+
ip.ipv4?
|
73
|
+
rescue ArgumentError
|
74
|
+
false
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def valid_alphabetical_ip_range?
|
79
|
+
VALID_ALPHABETICAL_VALUES_FOR_IP_RANGE.include?(data)
|
80
|
+
end
|
81
|
+
|
82
|
+
def valid_ip_address? ip_address
|
83
|
+
begin
|
84
|
+
#valid formats recognized by IPAddr are : “address”, “address/prefixlen” and “address/mask”.
|
85
|
+
# Attribute like member_ip in case of load-balancer is an "address"
|
86
|
+
# and we should not accept “address/prefixlen” and “address/mask” for such fields.
|
87
|
+
ip = IPAddr.new(ip_address)
|
88
|
+
ip.ipv4? && !ip_address.include?('/')
|
89
|
+
rescue ArgumentError
|
90
|
+
false
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def valid_ip_range?
|
95
|
+
range_parts = data.split('-')
|
96
|
+
return false if range_parts.size != 2
|
97
|
+
start_address = range_parts.first
|
98
|
+
end_address = range_parts.last
|
99
|
+
valid_ip_address?(start_address) && valid_ip_address?(end_address) &&
|
100
|
+
valid_start_and_end_address_combination?(end_address, start_address)
|
101
|
+
end
|
102
|
+
|
103
|
+
def valid_start_and_end_address_combination?(end_address, start_address)
|
104
|
+
IPAddr.new(start_address) < IPAddr.new(end_address)
|
105
|
+
end
|
106
|
+
|
107
|
+
def validate_hash
|
108
|
+
unless data.is_a? Hash
|
109
|
+
@errors << "#{key}: is not a hash"
|
110
|
+
return
|
111
|
+
end
|
112
|
+
return unless check_emptyness_ok
|
113
|
+
check_for_unknown_parameters
|
114
|
+
if schema.key?(:internals)
|
115
|
+
internals = schema[:internals]
|
116
|
+
internals.each do |param_key,param_schema|
|
117
|
+
check_hash_parameter(param_key, param_schema)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def validate_array
|
123
|
+
unless data.is_a? Array
|
124
|
+
@errors << "#{key} is not an array"
|
125
|
+
return
|
126
|
+
end
|
127
|
+
return unless check_emptyness_ok
|
128
|
+
if schema.key?(:each_element_is)
|
129
|
+
element_schema = schema[:each_element_is]
|
130
|
+
data.each do |element|
|
131
|
+
sub_validator = ConfigValidator.validate(key, element, element_schema)
|
132
|
+
unless sub_validator.valid?
|
133
|
+
@errors = errors + sub_validator.errors
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def validate_enum
|
140
|
+
unless (acceptable_values = schema[:acceptable_values]) && acceptable_values.is_a?(Array)
|
141
|
+
raise "Must set :acceptable_values for type 'enum'"
|
142
|
+
end
|
143
|
+
unless acceptable_values.include?(data)
|
144
|
+
acceptable_values_string = acceptable_values.collect {|v| "'#{v}'" }.join(', ')
|
145
|
+
@errors << "#{key}: #{@data} is not a valid value. Acceptable values are #{acceptable_values_string}."
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def validate_boolean
|
150
|
+
unless [true, false].include?(data)
|
151
|
+
@errors << "#{key}: #{data} is not a valid boolean value."
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def check_emptyness_ok
|
156
|
+
unless schema.key?(:allowed_empty) && schema[:allowed_empty]
|
157
|
+
if data.empty?
|
158
|
+
@errors << "#{key}: cannot be empty #{type}"
|
159
|
+
return false
|
160
|
+
end
|
161
|
+
end
|
162
|
+
true
|
163
|
+
end
|
164
|
+
|
165
|
+
def check_matcher_matches
|
166
|
+
return unless regex = schema[:matcher]
|
167
|
+
raise "#{key}: #{regex} is not a Regexp" unless regex.is_a? Regexp
|
168
|
+
unless data =~ regex
|
169
|
+
@errors << "#{key}: #{data} does not match"
|
170
|
+
return false
|
171
|
+
end
|
172
|
+
true
|
173
|
+
end
|
174
|
+
|
175
|
+
def check_hash_parameter(sub_key, sub_schema)
|
176
|
+
if sub_schema.key?(:required) && sub_schema[:required] == false
|
177
|
+
# short circuit out if we do not have the key, but it's not required.
|
178
|
+
return true unless data.key?(sub_key)
|
179
|
+
end
|
180
|
+
unless data.key?(sub_key)
|
181
|
+
@errors << "#{key}: missing '#{sub_key}' parameter"
|
182
|
+
return false
|
183
|
+
end
|
184
|
+
sub_validator = ConfigValidator.validate(
|
185
|
+
sub_key,
|
186
|
+
data[sub_key],
|
187
|
+
sub_schema
|
188
|
+
)
|
189
|
+
unless sub_validator.valid?
|
190
|
+
@errors = errors + sub_validator.errors
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def check_for_unknown_parameters
|
195
|
+
unless internals = schema[:internals]
|
196
|
+
# if there are no parameters specified, then assume all are ok.
|
197
|
+
return true
|
198
|
+
end
|
199
|
+
if schema[:permit_unknown_parameters]
|
200
|
+
return true
|
201
|
+
end
|
202
|
+
data.keys.each do |k|
|
203
|
+
@errors << "#{key}: parameter '#{k}' is invalid" unless internals[k]
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
data/lib/vcloud/core/version.rb
CHANGED
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Vcloud
|
4
|
+
module Core
|
5
|
+
describe ConfigLoader do
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
@data_dir = File.join(File.dirname(__FILE__), "/data")
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should create a valid hash when input is JSON" do
|
12
|
+
input_file = "#{@data_dir}/working.json"
|
13
|
+
loader = ConfigLoader.new
|
14
|
+
actual_config = loader.load_config(input_file)
|
15
|
+
valid_config.should eq(actual_config)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should create a valid hash when input is YAML" do
|
19
|
+
input_file = "#{@data_dir}/working.yaml"
|
20
|
+
loader = ConfigLoader.new
|
21
|
+
actual_config = loader.load_config(input_file)
|
22
|
+
valid_config.should eq(actual_config)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should create a valid hash when input is YAML with anchor defaults" do
|
26
|
+
input_file = "#{@data_dir}/working_with_defaults.yaml"
|
27
|
+
loader = ConfigLoader.new
|
28
|
+
actual_config = loader.load_config(input_file)
|
29
|
+
valid_config['vapps'].should eq(actual_config['vapps'])
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should validate correctly against a schema" do
|
33
|
+
input_file = "#{@data_dir}/working_with_defaults.yaml"
|
34
|
+
loader = ConfigLoader.new
|
35
|
+
schema = vapp_config_schema
|
36
|
+
actual_config = loader.load_config(input_file, schema)
|
37
|
+
valid_config['vapps'].should eq(actual_config['vapps'])
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should raise an error if checked against an invalid schema" do
|
41
|
+
input_file = "#{@data_dir}/working_with_defaults.yaml"
|
42
|
+
loader = ConfigLoader.new
|
43
|
+
Vcloud::Core.logger.should_receive(:fatal).with("vapps: is not a hash")
|
44
|
+
expect { loader.load_config(input_file, invalid_schema) }.
|
45
|
+
to raise_error('Supplied configuration does not match supplied schema')
|
46
|
+
end
|
47
|
+
|
48
|
+
def vapp_config_schema
|
49
|
+
{
|
50
|
+
type: 'hash',
|
51
|
+
allowed_empty: false,
|
52
|
+
permit_unknown_parameters: true,
|
53
|
+
internals: {
|
54
|
+
vapps: {
|
55
|
+
type: 'array',
|
56
|
+
required: false,
|
57
|
+
allowed_empty: true,
|
58
|
+
},
|
59
|
+
}
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
def invalid_schema
|
64
|
+
{
|
65
|
+
type: Hash,
|
66
|
+
permit_unknown_parameters: true,
|
67
|
+
internals: {
|
68
|
+
vapps: { type: Hash },
|
69
|
+
}
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
def valid_config
|
74
|
+
{
|
75
|
+
:vapps=>[{
|
76
|
+
:name=>"vapp-vcloud-tools-tests",
|
77
|
+
:vdc_name=>"VDC_NAME",
|
78
|
+
:catalog=>"CATALOG_NAME",
|
79
|
+
:catalog_item=>"CATALOG_ITEM",
|
80
|
+
:vm=>{
|
81
|
+
:hardware_config=>{:memory=>"4096", :cpu=>"2"},
|
82
|
+
:extra_disks=>[{:size=>"8192"}],
|
83
|
+
:network_connections=>[{
|
84
|
+
:name=>"Default",
|
85
|
+
:ip_address=>"192.168.2.10"
|
86
|
+
},
|
87
|
+
{
|
88
|
+
:name=>"NetworkTest2",
|
89
|
+
:ip_address=>"192.168.1.10"
|
90
|
+
}],
|
91
|
+
:bootstrap=>{
|
92
|
+
:script_path=>"spec/data/basic_preamble_test.erb",
|
93
|
+
:vars=>{:message=>"hello world"}
|
94
|
+
},
|
95
|
+
:metadata=>{}
|
96
|
+
}
|
97
|
+
}]
|
98
|
+
}
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,572 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Vcloud
|
4
|
+
module Core
|
5
|
+
describe ConfigValidator do
|
6
|
+
|
7
|
+
context "sanitize type" do
|
8
|
+
|
9
|
+
it "should be ok with type as bare String" do
|
10
|
+
data = "hello world"
|
11
|
+
schema = { type: String }
|
12
|
+
v = ConfigValidator.validate(:base, data, schema)
|
13
|
+
expect(v.valid?).to be_true
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should be ok with type as string 'String'" do
|
17
|
+
data = "hello world"
|
18
|
+
schema = { type: 'String' }
|
19
|
+
v = ConfigValidator.validate(:base, data, schema)
|
20
|
+
expect(v.valid?).to be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be ok with type as string 'string'" do
|
24
|
+
data = "hello world"
|
25
|
+
schema = { type: 'string' }
|
26
|
+
v = ConfigValidator.validate(:base, data, schema)
|
27
|
+
expect(v.valid?).to be_true
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
context "string validations" do
|
33
|
+
|
34
|
+
it "should validate a basic string" do
|
35
|
+
data = "hello world"
|
36
|
+
schema = { type: 'string' }
|
37
|
+
v = ConfigValidator.validate(:base, data, schema)
|
38
|
+
expect(v.valid?).to be_true
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should not validate a number as a basic string" do
|
42
|
+
data = 42
|
43
|
+
schema = { type: 'string' }
|
44
|
+
v = ConfigValidator.validate(:base, data, schema)
|
45
|
+
expect(v.valid?).to be_false
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should log error with number as a basic string" do
|
49
|
+
data = 42
|
50
|
+
schema = { type: 'string' }
|
51
|
+
v = ConfigValidator.validate(:base, data, schema)
|
52
|
+
expect(v.errors).to eq([ 'base: 42 is not a string'] )
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return error with empty string (by default)" do
|
56
|
+
data = ""
|
57
|
+
schema = { type: 'string' }
|
58
|
+
v = ConfigValidator.validate(:base, data, schema)
|
59
|
+
expect(v.errors).to eq([ 'base: cannot be empty string'] )
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should return error with empty string with allowed_empty: false)" do
|
63
|
+
data = ""
|
64
|
+
schema = { type: 'string', allowed_empty: false }
|
65
|
+
v = ConfigValidator.validate(:base, data, schema)
|
66
|
+
expect(v.errors).to eq([ 'base: cannot be empty string'] )
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should validate ok with empty string with allowed_empty: true)" do
|
70
|
+
data = ""
|
71
|
+
schema = { type: 'string', allowed_empty: true }
|
72
|
+
v = ConfigValidator.validate(:base, data, schema)
|
73
|
+
expect(v.valid?).to be_true
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should validate ok with a :matcher regex specified" do
|
77
|
+
data = "name-1234"
|
78
|
+
schema = { type: 'string', matcher: /^name-\d+$/ }
|
79
|
+
v = ConfigValidator.validate(:base, data, schema)
|
80
|
+
expect(v.valid?).to be_true
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should return errror with a :matcher regex not matching" do
|
84
|
+
data = "name-123a"
|
85
|
+
schema = { type: 'string', matcher: /^name-\d+$/ }
|
86
|
+
v = ConfigValidator.validate(:base, data, schema)
|
87
|
+
expect(v.errors).to eq(['base: name-123a does not match'])
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
context "hash validations" do
|
93
|
+
|
94
|
+
it "should validate a basic hash" do
|
95
|
+
data = { name: "santa", address: "north pole" }
|
96
|
+
schema = {
|
97
|
+
type: "Hash",
|
98
|
+
internals: {
|
99
|
+
name: { type: 'string' },
|
100
|
+
address: { type: 'string' },
|
101
|
+
}
|
102
|
+
}
|
103
|
+
v = ConfigValidator.validate(:base, data, schema)
|
104
|
+
expect(v.valid?).to be_true
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should not validate a bogus hash" do
|
108
|
+
data = { name: 42, address: 42 }
|
109
|
+
schema = {
|
110
|
+
type: "Hash",
|
111
|
+
internals: {
|
112
|
+
name: { type: "string" },
|
113
|
+
address: { type: "string" },
|
114
|
+
}
|
115
|
+
}
|
116
|
+
v = ConfigValidator.validate(:base, data, schema)
|
117
|
+
expect(v.valid?).to be_false
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should return correct errors validating a bogus hash" do
|
121
|
+
data = { name: 42, address: 42 }
|
122
|
+
schema = {
|
123
|
+
type: "Hash",
|
124
|
+
internals: {
|
125
|
+
name: { type: "string" },
|
126
|
+
address: { type: "string" },
|
127
|
+
}
|
128
|
+
}
|
129
|
+
v = ConfigValidator.validate(:base, data, schema)
|
130
|
+
expect(v.errors).to eq([
|
131
|
+
"name: 42 is not a string",
|
132
|
+
"address: 42 is not a string",
|
133
|
+
])
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should return error with empty hash (by default)" do
|
137
|
+
data = {}
|
138
|
+
schema = { type: 'hash' }
|
139
|
+
v = ConfigValidator.validate(:base, data, schema)
|
140
|
+
expect(v.errors).to eq([ 'base: cannot be empty hash'] )
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should return error with empty hash with allowed_empty: false)" do
|
144
|
+
data = {}
|
145
|
+
schema = { type: 'hash', allowed_empty: false }
|
146
|
+
v = ConfigValidator.validate(:base, data, schema)
|
147
|
+
expect(v.errors).to eq([ 'base: cannot be empty hash'] )
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should validate ok with empty hash with allowed_empty: true)" do
|
151
|
+
data = {}
|
152
|
+
schema = { type: 'hash', allowed_empty: true }
|
153
|
+
v = ConfigValidator.validate(:base, data, schema)
|
154
|
+
expect(v.valid?).to be_true
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should validate ok with a missing parameter, when marked :required => false" do
|
158
|
+
data = {
|
159
|
+
name: 'hello'
|
160
|
+
}
|
161
|
+
schema = {
|
162
|
+
type: 'hash',
|
163
|
+
internals: {
|
164
|
+
name: { type: 'string' },
|
165
|
+
optional_param: { type: 'string', required: false },
|
166
|
+
}
|
167
|
+
}
|
168
|
+
v = ConfigValidator.validate(:base, data, schema)
|
169
|
+
expect(v.valid?).to be_true
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should return error with a missing :required => true param" do
|
173
|
+
data = {
|
174
|
+
name: 'hello'
|
175
|
+
}
|
176
|
+
schema = {
|
177
|
+
type: 'hash',
|
178
|
+
internals: {
|
179
|
+
name: { type: 'string' },
|
180
|
+
not_optional_param: { type: 'string', required: true },
|
181
|
+
}
|
182
|
+
}
|
183
|
+
v = ConfigValidator.validate(:base, data, schema)
|
184
|
+
expect(v.errors).to eq(["base: missing 'not_optional_param' parameter"])
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should return error if a bogus parameter is specified" do
|
188
|
+
data = {
|
189
|
+
name: 'hello',
|
190
|
+
bogus_parameter: [ 'wibble' ],
|
191
|
+
bogus_parameter2: 'hello',
|
192
|
+
}
|
193
|
+
schema = {
|
194
|
+
type: 'hash',
|
195
|
+
internals: {
|
196
|
+
name: { type: 'string' },
|
197
|
+
},
|
198
|
+
}
|
199
|
+
v = ConfigValidator.validate(:base, data, schema)
|
200
|
+
expect(v.errors).to eq([
|
201
|
+
"base: parameter 'bogus_parameter' is invalid",
|
202
|
+
"base: parameter 'bogus_parameter2' is invalid",
|
203
|
+
])
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should validate ok if a bogus parameter is specified, when :permit_unknown_parameters is true" do
|
207
|
+
data = {
|
208
|
+
name: 'hello',
|
209
|
+
bogus_parameter: [ 'wibble' ],
|
210
|
+
bogus_parameter2: 'hello',
|
211
|
+
}
|
212
|
+
schema = {
|
213
|
+
type: 'hash',
|
214
|
+
permit_unknown_parameters: true,
|
215
|
+
internals: {
|
216
|
+
name: { type: 'string' },
|
217
|
+
},
|
218
|
+
}
|
219
|
+
v = ConfigValidator.validate(:base, data, schema)
|
220
|
+
expect(v.valid?).to be_true
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
224
|
+
|
225
|
+
context "array validations" do
|
226
|
+
|
227
|
+
it "should validate a basic array" do
|
228
|
+
data = [ "santa", "north pole" ]
|
229
|
+
schema = {
|
230
|
+
type: "Array",
|
231
|
+
each_element_is: { type: "string" }
|
232
|
+
}
|
233
|
+
v = ConfigValidator.validate(:base, data, schema)
|
234
|
+
expect(v.valid?).to be_true
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should validate a bogus array" do
|
238
|
+
data = [ 42, 43 ]
|
239
|
+
schema = {
|
240
|
+
type: "Array",
|
241
|
+
each_element_is: { type: "string" }
|
242
|
+
}
|
243
|
+
v = ConfigValidator.validate(:base, data, schema)
|
244
|
+
expect(v.valid?).to be_false
|
245
|
+
end
|
246
|
+
|
247
|
+
it "should return correct errors validating a bogus array" do
|
248
|
+
data = [ 42, 43 ]
|
249
|
+
schema = {
|
250
|
+
type: "Array",
|
251
|
+
each_element_is: { type: "string" }
|
252
|
+
}
|
253
|
+
v = ConfigValidator.validate(:base, data, schema)
|
254
|
+
expect(v.errors).to eq([
|
255
|
+
"base: 42 is not a string",
|
256
|
+
"base: 43 is not a string",
|
257
|
+
])
|
258
|
+
end
|
259
|
+
|
260
|
+
it "should return error with empty array (by default)" do
|
261
|
+
data = []
|
262
|
+
schema = { type: 'array' }
|
263
|
+
v = ConfigValidator.validate(:base, data, schema)
|
264
|
+
expect(v.errors).to eq([ 'base: cannot be empty array'] )
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should return error with empty array with allowed_empty: false)" do
|
268
|
+
data = []
|
269
|
+
schema = { type: 'array', allowed_empty: false }
|
270
|
+
v = ConfigValidator.validate(:base, data, schema)
|
271
|
+
expect(v.errors).to eq([ 'base: cannot be empty array'] )
|
272
|
+
end
|
273
|
+
|
274
|
+
it "should validate ok with empty array with allowed_empty: true)" do
|
275
|
+
data = []
|
276
|
+
schema = { type: 'array', allowed_empty: true }
|
277
|
+
v = ConfigValidator.validate(:base, data, schema)
|
278
|
+
expect(v.valid?).to be_true
|
279
|
+
end
|
280
|
+
|
281
|
+
end
|
282
|
+
|
283
|
+
context "array of hashes validations" do
|
284
|
+
|
285
|
+
it "should validate an array of hashes" do
|
286
|
+
data = [
|
287
|
+
{ name: "santa", address: "north pole" },
|
288
|
+
{ name: "mole", address: "1 hole street" },
|
289
|
+
]
|
290
|
+
schema = {
|
291
|
+
type: "array",
|
292
|
+
each_element_is: {
|
293
|
+
type: "hash",
|
294
|
+
internals: {
|
295
|
+
name: { type: 'string' },
|
296
|
+
address: { type: 'string' },
|
297
|
+
}
|
298
|
+
}
|
299
|
+
}
|
300
|
+
v = ConfigValidator.validate(:base, data, schema)
|
301
|
+
expect(v.valid?).to be_true
|
302
|
+
end
|
303
|
+
|
304
|
+
it "should correctly error on an invalid an array of hashes" do
|
305
|
+
data = [
|
306
|
+
{ name: "santa", address: [] },
|
307
|
+
{ name: 43, address: "1 hole street" },
|
308
|
+
]
|
309
|
+
schema = {
|
310
|
+
type: "array",
|
311
|
+
each_element_is: {
|
312
|
+
type: "hash",
|
313
|
+
internals: {
|
314
|
+
name: { type: 'string' },
|
315
|
+
address: { type: 'string' },
|
316
|
+
}
|
317
|
+
}
|
318
|
+
}
|
319
|
+
v = ConfigValidator.validate(:base, data, schema)
|
320
|
+
expect(v.errors).to eq([
|
321
|
+
"address: [] is not a string",
|
322
|
+
"name: 43 is not a string",
|
323
|
+
])
|
324
|
+
end
|
325
|
+
|
326
|
+
end
|
327
|
+
|
328
|
+
context "hash of arrays validations" do
|
329
|
+
|
330
|
+
it "should validate a hash of arrays" do
|
331
|
+
data = {
|
332
|
+
boys_names: [ 'bob', 'andrew', 'charlie', 'dave' ],
|
333
|
+
girls_names: [ 'alice', 'beth', 'carol', 'davina' ],
|
334
|
+
}
|
335
|
+
schema = {
|
336
|
+
type: "Hash",
|
337
|
+
internals: {
|
338
|
+
boys_names: {
|
339
|
+
type: "Array",
|
340
|
+
each_element_is: { type: 'String' }
|
341
|
+
},
|
342
|
+
girls_names: {
|
343
|
+
type: "Array",
|
344
|
+
each_element_is: { type: 'String' }
|
345
|
+
}
|
346
|
+
}
|
347
|
+
}
|
348
|
+
v = ConfigValidator.validate(:base, data, schema)
|
349
|
+
expect(v.valid?).to be_true
|
350
|
+
end
|
351
|
+
|
352
|
+
it "should correctly error on an invalid hash of arrays" do
|
353
|
+
data = {
|
354
|
+
boys_names: [ 'bob', 'andrew', 'charlie', 'dave' ],
|
355
|
+
girls_names: [ 'alice', 'beth', 'carol', 'davina' ],
|
356
|
+
}
|
357
|
+
schema = {
|
358
|
+
type: "Hash",
|
359
|
+
internals: {
|
360
|
+
boys_names: {
|
361
|
+
type: "Array",
|
362
|
+
each_element_is: { type: 'String' },
|
363
|
+
},
|
364
|
+
girls_names: {
|
365
|
+
type: "Array",
|
366
|
+
each_element_is: { type: 'String' },
|
367
|
+
}
|
368
|
+
},
|
369
|
+
}
|
370
|
+
v = ConfigValidator.validate(:base, data, schema)
|
371
|
+
expect(v.valid?).to be_true
|
372
|
+
end
|
373
|
+
|
374
|
+
end
|
375
|
+
|
376
|
+
context "string_or_number validations" do
|
377
|
+
|
378
|
+
it "should correctly validate an Integer" do
|
379
|
+
data = 2
|
380
|
+
schema = { type: 'string_or_number' }
|
381
|
+
v = ConfigValidator.validate(:base, data, schema)
|
382
|
+
expect(v.valid?).to be_true
|
383
|
+
end
|
384
|
+
|
385
|
+
it "should correctly validate a String" do
|
386
|
+
data = '2'
|
387
|
+
schema = { type: 'string_or_number' }
|
388
|
+
v = ConfigValidator.validate(:base, data, schema)
|
389
|
+
expect(v.valid?).to be_true
|
390
|
+
end
|
391
|
+
|
392
|
+
it "should correctly error if not a string or numeric" do
|
393
|
+
data = []
|
394
|
+
schema = { type: 'string_or_number' }
|
395
|
+
v = ConfigValidator.validate(:base, data, schema)
|
396
|
+
expect(v.errors).to eq(["base: [] is not a string_or_number"])
|
397
|
+
end
|
398
|
+
|
399
|
+
end
|
400
|
+
|
401
|
+
context "ip_address validations" do
|
402
|
+
|
403
|
+
it "should correctly validate an IP address" do
|
404
|
+
data = '192.168.100.100'
|
405
|
+
schema = { type: 'ip_address' }
|
406
|
+
v = ConfigValidator.validate(:base, data, schema)
|
407
|
+
expect(v.valid?).to be_true
|
408
|
+
end
|
409
|
+
|
410
|
+
it "should correctly error on an invalid IP address" do
|
411
|
+
data = '256.168.100.100'
|
412
|
+
schema = { type: 'ip_address' }
|
413
|
+
v = ConfigValidator.validate(:base, data, schema)
|
414
|
+
expect(v.errors).to eq(['base: 256.168.100.100 is not a valid ip_address'])
|
415
|
+
end
|
416
|
+
|
417
|
+
it "should error if ip address have wrong octets" do
|
418
|
+
data = '192.168.100.100/33/33/33'
|
419
|
+
schema = { type: 'ip_address' }
|
420
|
+
v = ConfigValidator.validate(:base, data, schema)
|
421
|
+
expect(v.errors).to eq(['base: 192.168.100.100/33/33/33 is not a valid ip_address'])
|
422
|
+
end
|
423
|
+
|
424
|
+
end
|
425
|
+
|
426
|
+
context "ip_address_range validations" do
|
427
|
+
context "validate CIDR" do
|
428
|
+
it "should validate OK if CIDR is correct" do
|
429
|
+
data = '192.168.100.100/24'
|
430
|
+
schema = { type: 'ip_address_range' }
|
431
|
+
v = ConfigValidator.validate(:base, data, schema)
|
432
|
+
expect(v.valid?).to be_true
|
433
|
+
end
|
434
|
+
|
435
|
+
it "should return error if network bit value is greater than 32" do
|
436
|
+
data = '192.168.100.100/33'
|
437
|
+
schema = { type: 'ip_address_range' }
|
438
|
+
v = ConfigValidator.validate(:base, data, schema)
|
439
|
+
expect(v.valid?).to be_false
|
440
|
+
expect(v.errors).to eq(["base: 192.168.100.100/33 is not a valid IP address range. Valid values can be IP address, CIDR, IP range, 'Any','internal' and 'external'."])
|
441
|
+
end
|
442
|
+
|
443
|
+
it "should return error if network bit value is less than 0" do
|
444
|
+
data = '192.168.100.100/33'
|
445
|
+
schema = { type: 'ip_address_range' }
|
446
|
+
v = ConfigValidator.validate(:base, data, schema)
|
447
|
+
expect(v.valid?).to be_false
|
448
|
+
expect(v.errors).to eq(["base: 192.168.100.100/33 is not a valid IP address range. Valid values can be IP address, CIDR, IP range, 'Any','internal' and 'external'."])
|
449
|
+
end
|
450
|
+
|
451
|
+
it "should return error if network IP address is incorrect" do
|
452
|
+
data = '192.168.100./33'
|
453
|
+
schema = { type: 'ip_address_range' }
|
454
|
+
v = ConfigValidator.validate(:base, data, schema)
|
455
|
+
expect(v.valid?).to be_false
|
456
|
+
expect(v.errors).to eq(["base: 192.168.100./33 is not a valid IP address range. Valid values can be IP address, CIDR, IP range, 'Any','internal' and 'external'."])
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
context "validate alphabetical values for IP range" do
|
461
|
+
%w(Any internal external).each do |data|
|
462
|
+
it "should validate OK if IP range is '#{data}'" do
|
463
|
+
schema = { type: 'ip_address_range' }
|
464
|
+
v = ConfigValidator.validate(:base, data, schema)
|
465
|
+
expect(v.valid?).to be_true
|
466
|
+
expect(v.errors).to be_empty
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
it "should error if IP range is a string but not a valid alphabetical value" do
|
471
|
+
data = 'invalid_ip_range_string'
|
472
|
+
schema = { type: 'ip_address_range' }
|
473
|
+
v = ConfigValidator.validate(:base, data, schema)
|
474
|
+
expect(v.valid?).to be_false
|
475
|
+
expect(v.errors).to eq(["base: invalid_ip_range_string is not a valid IP address range. Valid values can be IP address, CIDR, IP range, 'Any','internal' and 'external'."])
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
context "validate ranges specified using start and end addresses" do
|
480
|
+
it "should validate ok if the combination of start IP and end IP is correct" do
|
481
|
+
data = '192.168.100.100-192.168.100.110'
|
482
|
+
schema = { type: 'ip_address_range' }
|
483
|
+
v = ConfigValidator.validate(:base, data, schema)
|
484
|
+
expect(v.valid?).to be_true
|
485
|
+
expect(v.errors).to be_empty
|
486
|
+
end
|
487
|
+
|
488
|
+
it "should error if start IP address is incorrect" do
|
489
|
+
data = '192.168.100-192.168.100.110'
|
490
|
+
schema = { type: 'ip_address_range' }
|
491
|
+
v = ConfigValidator.validate(:base, data, schema)
|
492
|
+
expect(v.valid?).to be_false
|
493
|
+
expect(v.errors).to eq(["base: 192.168.100-192.168.100.110 is not a valid IP address range. Valid values can be IP address, CIDR, IP range, 'Any','internal' and 'external'."])
|
494
|
+
end
|
495
|
+
|
496
|
+
it "should error if end IP address is incorrect" do
|
497
|
+
data = '192.168.100.110-192.168.100'
|
498
|
+
schema = { type: 'ip_address_range' }
|
499
|
+
v = ConfigValidator.validate(:base, data, schema)
|
500
|
+
expect(v.valid?).to be_false
|
501
|
+
expect(v.errors).to eq(["base: 192.168.100.110-192.168.100 is not a valid IP address range. Valid values can be IP address, CIDR, IP range, 'Any','internal' and 'external'."])
|
502
|
+
end
|
503
|
+
|
504
|
+
it "should error if the combination of start IP and end IP is incorrect" do
|
505
|
+
data = '200.168.100.99-192.168.100'
|
506
|
+
schema = { type: 'ip_address_range' }
|
507
|
+
v = ConfigValidator.validate(:base, data, schema)
|
508
|
+
expect(v.valid?).to be_false
|
509
|
+
expect(v.errors).to eq(["base: 200.168.100.99-192.168.100 is not a valid IP address range. Valid values can be IP address, CIDR, IP range, 'Any','internal' and 'external'."])
|
510
|
+
end
|
511
|
+
|
512
|
+
it "should error if the start and end IPS are not separated by -" do
|
513
|
+
data = '190.168.100.99:192.168.100'
|
514
|
+
schema = { type: 'ip_address_range' }
|
515
|
+
v = ConfigValidator.validate(:base, data, schema)
|
516
|
+
expect(v.valid?).to be_false
|
517
|
+
expect(v.errors).to eq(["base: 190.168.100.99:192.168.100 is not a valid IP address range. Valid values can be IP address, CIDR, IP range, 'Any','internal' and 'external'."])
|
518
|
+
end
|
519
|
+
end
|
520
|
+
|
521
|
+
it "should accept single ip address as range" do
|
522
|
+
data = '190.168.100.99'
|
523
|
+
schema = { type: 'ip_address_range' }
|
524
|
+
v = ConfigValidator.validate(:base, data, schema)
|
525
|
+
expect(v.valid?).to be_true
|
526
|
+
expect(v.errors).to eq([])
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
context "enum validations" do
|
531
|
+
it "should error if enum value is not present in list" do
|
532
|
+
data = 'blah'
|
533
|
+
schema = { type: 'enum', required: false, acceptable_values: ['allow', 'decline', 'none']}
|
534
|
+
v = ConfigValidator.validate(:base, data, schema)
|
535
|
+
expect(v.errors).to eq(["base: blah is not a valid value. Acceptable values are 'allow', 'decline', 'none'."])
|
536
|
+
end
|
537
|
+
|
538
|
+
it "should raise error if enum schema does not contain acceptable_values" do
|
539
|
+
data = 'blah'
|
540
|
+
schema = { type: 'enum', required: false}
|
541
|
+
expect{ ConfigValidator.validate(:base, data, schema) }.to raise_error("Must set :acceptable_values for type 'enum'")
|
542
|
+
end
|
543
|
+
|
544
|
+
it "should validate ok if enum is acceptable" do
|
545
|
+
data = 'allow'
|
546
|
+
schema = { type: 'enum', required: false, acceptable_values: ['allow', 'decline', 'none']}
|
547
|
+
v = ConfigValidator.validate(:base, data, schema)
|
548
|
+
expect(v.valid?).to be_true
|
549
|
+
end
|
550
|
+
end
|
551
|
+
|
552
|
+
context "boolean validations" do
|
553
|
+
it "should error if boolean value is not valid" do
|
554
|
+
data = 'blah'
|
555
|
+
schema = { type: 'boolean' }
|
556
|
+
v = ConfigValidator.validate(:base, data, schema)
|
557
|
+
expect(v.errors).to eq(["base: blah is not a valid boolean value."])
|
558
|
+
end
|
559
|
+
|
560
|
+
[true, false].each do |boolean_value|
|
561
|
+
it "should validate ok if value is #{boolean_value}" do
|
562
|
+
schema = { type: 'boolean' }
|
563
|
+
v = ConfigValidator.validate(:base, boolean_value, schema)
|
564
|
+
expect(v.valid?).to be_true
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
end
|
569
|
+
|
570
|
+
end
|
571
|
+
end
|
572
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
{
|
2
|
+
"vapps":[{
|
3
|
+
"name":"vapp-vcloud-tools-tests",
|
4
|
+
"vdc_name":"VDC_NAME",
|
5
|
+
"catalog":"CATALOG_NAME",
|
6
|
+
"catalog_item":"CATALOG_ITEM",
|
7
|
+
"vm":{
|
8
|
+
"hardware_config":{"memory":"4096", "cpu":"2"},
|
9
|
+
"extra_disks":[{"size":"8192"}],
|
10
|
+
"network_connections":[
|
11
|
+
{"name":"Default",
|
12
|
+
"ip_address":"192.168.2.10"},
|
13
|
+
{"name":"NetworkTest2",
|
14
|
+
"ip_address":"192.168.1.10"}
|
15
|
+
],
|
16
|
+
"bootstrap":{"script_path":"spec/data/basic_preamble_test.erb",
|
17
|
+
"vars":{"message":"hello world"}},
|
18
|
+
"metadata":{}
|
19
|
+
}
|
20
|
+
}]
|
21
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
---
|
2
|
+
vapps:
|
3
|
+
- name: vapp-vcloud-tools-tests
|
4
|
+
vdc_name: VDC_NAME
|
5
|
+
catalog: CATALOG_NAME
|
6
|
+
catalog_item: CATALOG_ITEM
|
7
|
+
vm:
|
8
|
+
hardware_config:
|
9
|
+
memory: '4096'
|
10
|
+
cpu: '2'
|
11
|
+
extra_disks:
|
12
|
+
- size: '8192'
|
13
|
+
network_connections:
|
14
|
+
- name: Default
|
15
|
+
ip_address: 192.168.2.10
|
16
|
+
- name: NetworkTest2
|
17
|
+
ip_address: 192.168.1.10
|
18
|
+
bootstrap:
|
19
|
+
script_path: 'spec/data/basic_preamble_test.erb'
|
20
|
+
vars:
|
21
|
+
message: 'hello world'
|
22
|
+
metadata: {}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
---
|
2
|
+
anchors:
|
3
|
+
- &VDC_NAME dcs-dev
|
4
|
+
|
5
|
+
vapps:
|
6
|
+
- name: vapp-vcloud-tools-tests
|
7
|
+
vdc_name: *VDC_NAME
|
8
|
+
catalog: CATALOG_NAME
|
9
|
+
catalog_item: CATALOG_ITEM
|
10
|
+
vm:
|
11
|
+
hardware_config:
|
12
|
+
memory: '4096'
|
13
|
+
cpu: '2'
|
14
|
+
extra_disks:
|
15
|
+
- size: '8192'
|
16
|
+
network_connections:
|
17
|
+
- name: Default
|
18
|
+
ip_address: 192.168.2.10
|
19
|
+
- name: NetworkTest2
|
20
|
+
ip_address: 192.168.1.10
|
21
|
+
bootstrap:
|
22
|
+
script_path: 'spec/data/basic_preamble_test.erb'
|
23
|
+
vars:
|
24
|
+
message: 'hello world'
|
25
|
+
metadata: {}
|
data/spec/vcloud/core/vm_spec.rb
CHANGED
@@ -9,7 +9,7 @@ module Vcloud
|
|
9
9
|
@vapp_id = 'vapp-4321'
|
10
10
|
@vapp_name = 'test-vapp-1'
|
11
11
|
@vm_name = 'test-vm-1'
|
12
|
-
@data_dir = File.join(File.dirname(__FILE__), "
|
12
|
+
@data_dir = File.join(File.dirname(__FILE__), "/data")
|
13
13
|
@mock_vm_memory_size = 1024
|
14
14
|
@mock_metadata = {
|
15
15
|
:foo => "bar",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vcloud-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-03-
|
12
|
+
date: 2014-03-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fog
|
@@ -126,6 +126,8 @@ files:
|
|
126
126
|
- jenkins.sh
|
127
127
|
- lib/vcloud/core.rb
|
128
128
|
- lib/vcloud/core/compute_metadata.rb
|
129
|
+
- lib/vcloud/core/config_loader.rb
|
130
|
+
- lib/vcloud/core/config_validator.rb
|
129
131
|
- lib/vcloud/core/edge_gateway.rb
|
130
132
|
- lib/vcloud/core/edge_gateway_interface.rb
|
131
133
|
- lib/vcloud/core/entity.rb
|
@@ -146,6 +148,13 @@ files:
|
|
146
148
|
- spec/integration/edge_gateway/edge_gateway_spec.rb
|
147
149
|
- spec/spec_helper.rb
|
148
150
|
- spec/support/stub_fog_interface.rb
|
151
|
+
- spec/vcloud/core/config_loader_spec.rb
|
152
|
+
- spec/vcloud/core/config_validator_spec.rb
|
153
|
+
- spec/vcloud/core/data/basic_preamble_test.erb
|
154
|
+
- spec/vcloud/core/data/basic_preamble_test.erb.OUT
|
155
|
+
- spec/vcloud/core/data/working.json
|
156
|
+
- spec/vcloud/core/data/working.yaml
|
157
|
+
- spec/vcloud/core/data/working_with_defaults.yaml
|
149
158
|
- spec/vcloud/core/edge_gateway_interface_spec.rb
|
150
159
|
- spec/vcloud/core/edge_gateway_spec.rb
|
151
160
|
- spec/vcloud/core/metadata_helper_spec.rb
|
@@ -155,8 +164,6 @@ files:
|
|
155
164
|
- spec/vcloud/core/vapp_template_spec.rb
|
156
165
|
- spec/vcloud/core/vdc_spec.rb
|
157
166
|
- spec/vcloud/core/vm_spec.rb
|
158
|
-
- spec/vcloud/data/basic_preamble_test.erb
|
159
|
-
- spec/vcloud/data/basic_preamble_test.erb.OUT
|
160
167
|
- spec/vcloud/fog/fog_model_interface_spec.rb
|
161
168
|
- spec/vcloud/fog/service_interface_spec.rb
|
162
169
|
- vcloud-core.gemspec
|
@@ -181,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
181
188
|
version: '0'
|
182
189
|
segments:
|
183
190
|
- 0
|
184
|
-
hash:
|
191
|
+
hash: -3857077396882591731
|
185
192
|
requirements: []
|
186
193
|
rubyforge_project:
|
187
194
|
rubygems_version: 1.8.23
|
@@ -193,6 +200,13 @@ test_files:
|
|
193
200
|
- spec/integration/edge_gateway/edge_gateway_spec.rb
|
194
201
|
- spec/spec_helper.rb
|
195
202
|
- spec/support/stub_fog_interface.rb
|
203
|
+
- spec/vcloud/core/config_loader_spec.rb
|
204
|
+
- spec/vcloud/core/config_validator_spec.rb
|
205
|
+
- spec/vcloud/core/data/basic_preamble_test.erb
|
206
|
+
- spec/vcloud/core/data/basic_preamble_test.erb.OUT
|
207
|
+
- spec/vcloud/core/data/working.json
|
208
|
+
- spec/vcloud/core/data/working.yaml
|
209
|
+
- spec/vcloud/core/data/working_with_defaults.yaml
|
196
210
|
- spec/vcloud/core/edge_gateway_interface_spec.rb
|
197
211
|
- spec/vcloud/core/edge_gateway_spec.rb
|
198
212
|
- spec/vcloud/core/metadata_helper_spec.rb
|
@@ -202,7 +216,5 @@ test_files:
|
|
202
216
|
- spec/vcloud/core/vapp_template_spec.rb
|
203
217
|
- spec/vcloud/core/vdc_spec.rb
|
204
218
|
- spec/vcloud/core/vm_spec.rb
|
205
|
-
- spec/vcloud/data/basic_preamble_test.erb
|
206
|
-
- spec/vcloud/data/basic_preamble_test.erb.OUT
|
207
219
|
- spec/vcloud/fog/fog_model_interface_spec.rb
|
208
220
|
- spec/vcloud/fog/service_interface_spec.rb
|