vcloud-core 0.3.0 → 0.4.0
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/.gitignore +2 -0
- data/CHANGELOG.md +17 -0
- data/README.md +3 -12
- data/Rakefile +1 -1
- data/jenkins.sh +6 -3
- data/jenkins_integration_tests.sh +8 -0
- data/lib/vcloud/core/config_loader.rb +3 -0
- data/lib/vcloud/core/config_validator.rb +179 -114
- data/lib/vcloud/core/edge_gateway_interface.rb +1 -1
- data/lib/vcloud/core/vapp_template.rb +3 -3
- data/lib/vcloud/core/version.rb +1 -1
- data/lib/vcloud/core/vm.rb +23 -5
- data/lib/vcloud/fog/content_types.rb +0 -2
- data/lib/vcloud/fog/service_interface.rb +0 -8
- data/spec/integration/README.md +36 -0
- data/spec/integration/{query → core}/query_runner_spec.rb +9 -43
- data/spec/integration/vcloud_tools_testing_config.yaml.template +6 -0
- data/spec/spec_helper.rb +4 -2
- data/spec/support/integration_helper.rb +32 -0
- data/spec/support/stub_fog_interface.rb +1 -1
- data/spec/vcloud/core/config_loader_spec.rb +49 -1
- data/spec/vcloud/core/config_validator_spec.rb +118 -0
- data/spec/vcloud/core/data/basic_preamble_test.erb +4 -0
- data/spec/vcloud/core/data/basic_preamble_test.erb.OUT +3 -0
- data/spec/vcloud/core/data/preamble_post_processor_test_input.erb +7 -0
- data/spec/vcloud/core/data/working.json +1 -1
- data/spec/vcloud/core/data/working.yaml +1 -1
- data/spec/vcloud/core/data/working_template.yaml +1 -1
- data/spec/vcloud/core/data/working_with_defaults.yaml +1 -1
- data/spec/vcloud/core/vapp_template_spec.rb +3 -7
- data/spec/vcloud/core/vm_spec.rb +15 -7
- data/vcloud-core.gemspec +1 -0
- metadata +29 -5
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
## 0.4.0 (2014-05-23)
|
2
|
+
|
3
|
+
Features:
|
4
|
+
|
5
|
+
- Add a 'warnings' variable/method to ConfigValidator.
|
6
|
+
- Support simple parameter deprecations in ConfigValidator.
|
7
|
+
- Log schema warnings encountered in ConfigLoader.
|
8
|
+
|
9
|
+
API changes:
|
10
|
+
|
11
|
+
- Breaking changes to the order and name of arguments for VappTemplate#get
|
12
|
+
- Remove unused methods Vcloud::Fog::ServiceInterface#get_catalog and
|
13
|
+
Vcloud::Fog::ServiceInterface#get_catalog_item, plus associated
|
14
|
+
Vcloud::Fog::ContentTypes constants.
|
15
|
+
- Restrict variable scope available to preamble ERB templates so that they
|
16
|
+
cannot access or modify the Vm object.
|
17
|
+
|
1
18
|
## 0.3.0 (2014-05-13)
|
2
19
|
|
3
20
|
Features:
|
data/README.md
CHANGED
@@ -153,18 +153,9 @@ Run the integration tests (slower and requires a real environment):
|
|
153
153
|
|
154
154
|
bundle exec rake integration
|
155
155
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
configuration: an Edge Gateway, and a routed network.
|
160
|
-
It is not necessarily safe to run them against an existing environment, unless care is taken with the entities being
|
161
|
-
tested.
|
162
|
-
|
163
|
-
A number of ENV vars specifying items under test in the environment need to be set for the tests to run successfully.
|
164
|
-
|
165
|
-
- `VCLOUD_EDGE_GATEWAY`: _name of edge gateway under test_
|
166
|
-
- `VCLOUD_NETWORK1_ID`: _Id of network under test_
|
167
|
-
- `VCLOUD_PROVIDER_NETWORK_ID`: _Id of the uplink network (or external network) of the VCLOUD_EDGE_GATEWAY under test_
|
156
|
+
You need access to a suitable vCloud Director organization to run the
|
157
|
+
integration tests. See the [integration tests README](/spec/integration/README.md) for
|
158
|
+
further details.
|
168
159
|
|
169
160
|
## Contributing
|
170
161
|
|
data/Rakefile
CHANGED
data/jenkins.sh
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
#!/bin/bash -x
|
2
2
|
set -e
|
3
3
|
|
4
|
-
|
5
|
-
git clean -fdx
|
6
|
-
|
4
|
+
git clean -ffdx
|
7
5
|
bundle install --path "${HOME}/bundles/${JOB_NAME}"
|
8
6
|
|
7
|
+
# Obtain the integration test parameters
|
8
|
+
git clone git@github.gds:gds/vcloud-tools-testing-config.git
|
9
|
+
mv vcloud-tools-testing-config/vcloud_tools_testing_config.yaml spec/integration/
|
10
|
+
rm -rf vcloud-tools-testing-config
|
11
|
+
|
9
12
|
bundle exec rake
|
10
13
|
RUBYOPT="-r ./tools/fog_credentials" bundle exec rake integration
|
11
14
|
bundle exec rake publish_gem
|
@@ -1,4 +1,12 @@
|
|
1
1
|
#!/bin/bash -x
|
2
2
|
set -e
|
3
|
+
|
4
|
+
git clean -ffdx
|
3
5
|
bundle install --path "${HOME}/bundles/${JOB_NAME}"
|
6
|
+
|
7
|
+
# Obtain the integration test parameters
|
8
|
+
git clone git@github.gds:gds/vcloud-tools-testing-config.git
|
9
|
+
mv vcloud-tools-testing-config/vcloud_tools_testing_config.yaml spec/integration/
|
10
|
+
rm -rf vcloud-tools-testing-config
|
11
|
+
|
4
12
|
RUBYOPT="-r ./tools/fog_credentials" bundle exec rake integration
|
@@ -21,6 +21,9 @@ module Vcloud
|
|
21
21
|
|
22
22
|
if schema
|
23
23
|
validation = Core::ConfigValidator.validate(:base, config, schema)
|
24
|
+
validation.warnings.each do |warning|
|
25
|
+
Vcloud::Core.logger.warn(warning)
|
26
|
+
end
|
24
27
|
unless validation.valid?
|
25
28
|
validation.errors.each do |error|
|
26
29
|
Vcloud::Core.logger.fatal(error)
|
@@ -1,18 +1,42 @@
|
|
1
1
|
require 'ipaddr'
|
2
2
|
|
3
|
+
##
|
4
|
+
# self::validate is entry point; this class method is called to
|
5
|
+
# instantiate ConfigValidator. For example:
|
6
|
+
#
|
7
|
+
# Core::ConfigValidator.validate(key, data, schema)
|
8
|
+
#
|
9
|
+
# = Recursion in this class
|
10
|
+
#
|
11
|
+
# Note that this class will recursively call itself in order to validate deep
|
12
|
+
# hash and array structures.
|
13
|
+
#
|
14
|
+
# The +data+ variable is usually either an array or hash and so will pass
|
15
|
+
# through the ConfigValidator#validate_array and
|
16
|
+
# ConfigValidator#validate_hash methods respectively.
|
17
|
+
#
|
18
|
+
# These methods then recursively instantiate this class by calling
|
19
|
+
# ConfigValidator::validate again (ConfigValidator#validate_hash calls this
|
20
|
+
# indirectly via the ConfigValidator#check_hash_parameter method).
|
21
|
+
|
3
22
|
module Vcloud
|
4
23
|
module Core
|
5
24
|
class ConfigValidator
|
6
25
|
|
7
|
-
attr_reader :key, :data, :schema, :type, :errors
|
26
|
+
attr_reader :key, :data, :schema, :type, :errors, :warnings
|
8
27
|
|
9
28
|
VALID_ALPHABETICAL_VALUES_FOR_IP_RANGE = %w(Any external internal)
|
10
29
|
|
30
|
+
def self.validate(key, data, schema)
|
31
|
+
new(key, data, schema)
|
32
|
+
end
|
33
|
+
|
11
34
|
def initialize(key, data, schema)
|
12
35
|
raise "Nil schema" unless schema
|
13
36
|
raise "Invalid schema" unless schema.key?(:type)
|
14
37
|
@type = schema[:type].to_s.downcase
|
15
|
-
@errors
|
38
|
+
@errors = []
|
39
|
+
@warnings = []
|
16
40
|
@data = data
|
17
41
|
@schema = schema
|
18
42
|
@key = key
|
@@ -23,47 +47,147 @@ module Vcloud
|
|
23
47
|
@errors.empty?
|
24
48
|
end
|
25
49
|
|
26
|
-
def self.validate(key, data, schema)
|
27
|
-
new(key, data, schema)
|
28
|
-
end
|
29
|
-
|
30
50
|
private
|
31
51
|
|
52
|
+
# Call the corresponding function in this class (dependant on schema[:type])
|
32
53
|
def validate
|
33
54
|
self.send("validate_#{type}".to_sym)
|
34
55
|
end
|
35
56
|
|
36
|
-
def
|
37
|
-
unless
|
38
|
-
errors << "#{key}
|
57
|
+
def validate_array
|
58
|
+
unless data.is_a? Array
|
59
|
+
@errors << "#{key} is not an array"
|
39
60
|
return
|
40
61
|
end
|
41
62
|
return unless check_emptyness_ok
|
42
|
-
|
63
|
+
if schema.key?(:each_element_is)
|
64
|
+
element_schema = schema[:each_element_is]
|
65
|
+
data.each do |element|
|
66
|
+
sub_validator = ConfigValidator.validate(key, element, element_schema)
|
67
|
+
@warnings = warnings + sub_validator.warnings
|
68
|
+
unless sub_validator.valid?
|
69
|
+
@errors = errors + sub_validator.errors
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
43
73
|
end
|
44
74
|
|
45
|
-
def
|
46
|
-
unless data.is_a?
|
47
|
-
@errors << "#{key}:
|
75
|
+
def validate_hash
|
76
|
+
unless data.is_a? Hash
|
77
|
+
@errors << "#{key}: is not a hash"
|
48
78
|
return
|
49
79
|
end
|
80
|
+
return unless check_emptyness_ok
|
81
|
+
check_for_unknown_parameters
|
82
|
+
|
83
|
+
if schema.key?(:internals)
|
84
|
+
check_for_invalid_deprecations
|
85
|
+
deprecations_used = get_deprecations_used
|
86
|
+
warn_on_deprecations_used(deprecations_used)
|
87
|
+
|
88
|
+
schema[:internals].each do |param_key,param_schema|
|
89
|
+
ignore_required = (
|
90
|
+
param_schema[:deprecated_by] ||
|
91
|
+
deprecations_used.key?(param_key)
|
92
|
+
)
|
93
|
+
check_hash_parameter(param_key, param_schema, ignore_required)
|
94
|
+
end
|
95
|
+
end
|
50
96
|
end
|
51
97
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
98
|
+
# Return a hash of deprecated params referenced in @data. Where the
|
99
|
+
# structure is: `{ :deprecator => :deprecatee }`
|
100
|
+
def get_deprecations_used
|
101
|
+
used = {}
|
102
|
+
schema[:internals].each do |param_key,param_schema|
|
103
|
+
deprecated_by = param_schema[:deprecated_by]
|
104
|
+
if deprecated_by && data[param_key]
|
105
|
+
used[deprecated_by.to_sym] = param_key
|
106
|
+
end
|
56
107
|
end
|
57
|
-
|
108
|
+
|
109
|
+
used
|
58
110
|
end
|
59
111
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
112
|
+
# Append warnings for any deprecations used. Takes the output of
|
113
|
+
# `#get_deprecations_used`.
|
114
|
+
def warn_on_deprecations_used(deprecations_used)
|
115
|
+
deprecations_used.each do |deprecator, deprecatee|
|
116
|
+
@warnings << "#{deprecatee}: is deprecated by '#{deprecator}'"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def check_emptyness_ok
|
121
|
+
unless schema.key?(:allowed_empty) && schema[:allowed_empty]
|
122
|
+
if data.empty?
|
123
|
+
@errors << "#{key}: cannot be empty #{type}"
|
124
|
+
return false
|
125
|
+
end
|
126
|
+
end
|
127
|
+
true
|
128
|
+
end
|
129
|
+
|
130
|
+
# Raise an exception if any `deprecated_by` params refer to params
|
131
|
+
# that don't exist in the schema.
|
132
|
+
def check_for_invalid_deprecations
|
133
|
+
schema[:internals].each do |param_key,param_schema|
|
134
|
+
deprecated_by = param_schema[:deprecated_by]
|
135
|
+
if deprecated_by && !schema[:internals].key?(deprecated_by.to_sym)
|
136
|
+
raise "#{param_key}: deprecated_by target '#{deprecated_by}' not found in schema"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def check_for_unknown_parameters
|
142
|
+
internals = schema[:internals]
|
143
|
+
# if there are no parameters specified, then assume all are ok.
|
144
|
+
return true unless internals
|
145
|
+
return true if schema[:permit_unknown_parameters]
|
146
|
+
data.keys.each do |k|
|
147
|
+
@errors << "#{key}: parameter '#{k}' is invalid" unless internals[k]
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def check_hash_parameter(sub_key, sub_schema, ignore_required=false)
|
152
|
+
unless data.key?(sub_key)
|
153
|
+
if sub_schema[:required] == false || ignore_required
|
154
|
+
return true
|
155
|
+
end
|
156
|
+
|
157
|
+
@errors << "#{key}: missing '#{sub_key}' parameter"
|
158
|
+
return false
|
159
|
+
end
|
160
|
+
|
161
|
+
sub_validator = ConfigValidator.validate(
|
162
|
+
sub_key,
|
163
|
+
data[sub_key],
|
164
|
+
sub_schema
|
165
|
+
)
|
166
|
+
@warnings = warnings + sub_validator.warnings
|
167
|
+
unless sub_validator.valid?
|
168
|
+
@errors = errors + sub_validator.errors
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def check_matcher_matches
|
173
|
+
regex = schema[:matcher]
|
174
|
+
return unless regex
|
175
|
+
raise "#{key}: #{regex} is not a Regexp" unless regex.is_a? Regexp
|
176
|
+
unless data =~ regex
|
177
|
+
@errors << "#{key}: #{data} does not match"
|
178
|
+
return false
|
179
|
+
end
|
180
|
+
true
|
181
|
+
end
|
182
|
+
|
183
|
+
def valid_alphabetical_ip_range?
|
184
|
+
VALID_ALPHABETICAL_VALUES_FOR_IP_RANGE.include?(data)
|
185
|
+
end
|
186
|
+
|
187
|
+
def validate_boolean
|
188
|
+
unless [true, false].include?(data)
|
189
|
+
@errors << "#{key}: #{data} is not a valid boolean value."
|
64
190
|
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
191
|
end
|
68
192
|
|
69
193
|
def valid_cidr_or_ip_address?
|
@@ -75,8 +199,21 @@ module Vcloud
|
|
75
199
|
end
|
76
200
|
end
|
77
201
|
|
78
|
-
def
|
79
|
-
|
202
|
+
def validate_enum
|
203
|
+
acceptable_values = schema[:acceptable_values]
|
204
|
+
raise "Must set :acceptable_values for type 'enum'" unless acceptable_values.is_a?(Array)
|
205
|
+
unless acceptable_values.include?(data)
|
206
|
+
acceptable_values_string = acceptable_values.collect {|v| "'#{v}'" }.join(', ')
|
207
|
+
@errors << "#{key}: #{@data} is not a valid value. Acceptable values are #{acceptable_values_string}."
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def validate_ip_address
|
212
|
+
unless data.is_a?(String)
|
213
|
+
@errors << "#{key}: #{@data} is not a valid ip_address"
|
214
|
+
return
|
215
|
+
end
|
216
|
+
@errors << "#{key}: #{@data} is not a valid ip_address" unless valid_ip_address?(data)
|
80
217
|
end
|
81
218
|
|
82
219
|
def valid_ip_address? ip_address
|
@@ -91,6 +228,15 @@ module Vcloud
|
|
91
228
|
end
|
92
229
|
end
|
93
230
|
|
231
|
+
def validate_ip_address_range
|
232
|
+
unless data.is_a?(String)
|
233
|
+
@errors << "#{key}: #{@data} is not a valid IP address range. Valid values can be IP address, CIDR, IP range, 'Any','internal' and 'external'."
|
234
|
+
return
|
235
|
+
end
|
236
|
+
valid = valid_cidr_or_ip_address? || valid_alphabetical_ip_range? || valid_ip_range?
|
237
|
+
@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
|
238
|
+
end
|
239
|
+
|
94
240
|
def valid_ip_range?
|
95
241
|
range_parts = data.split('-')
|
96
242
|
return false if range_parts.size != 2
|
@@ -104,101 +250,20 @@ module Vcloud
|
|
104
250
|
IPAddr.new(start_address) < IPAddr.new(end_address)
|
105
251
|
end
|
106
252
|
|
107
|
-
def
|
108
|
-
unless data.is_a?
|
109
|
-
|
253
|
+
def validate_string
|
254
|
+
unless @data.is_a? String
|
255
|
+
errors << "#{key}: #{@data} is not a string"
|
110
256
|
return
|
111
257
|
end
|
112
258
|
return unless check_emptyness_ok
|
113
|
-
|
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
|
259
|
+
return unless check_matcher_matches
|
120
260
|
end
|
121
261
|
|
122
|
-
def
|
123
|
-
unless data.is_a?
|
124
|
-
@errors << "#{key} is not
|
262
|
+
def validate_string_or_number
|
263
|
+
unless data.is_a?(String) || data.is_a?(Numeric)
|
264
|
+
@errors << "#{key}: #{@data} is not a string_or_number"
|
125
265
|
return
|
126
266
|
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
|
-
acceptable_values = schema[:acceptable_values]
|
141
|
-
raise "Must set :acceptable_values for type 'enum'" unless acceptable_values.is_a?(Array)
|
142
|
-
unless acceptable_values.include?(data)
|
143
|
-
acceptable_values_string = acceptable_values.collect {|v| "'#{v}'" }.join(', ')
|
144
|
-
@errors << "#{key}: #{@data} is not a valid value. Acceptable values are #{acceptable_values_string}."
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
def validate_boolean
|
149
|
-
unless [true, false].include?(data)
|
150
|
-
@errors << "#{key}: #{data} is not a valid boolean value."
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
def check_emptyness_ok
|
155
|
-
unless schema.key?(:allowed_empty) && schema[:allowed_empty]
|
156
|
-
if data.empty?
|
157
|
-
@errors << "#{key}: cannot be empty #{type}"
|
158
|
-
return false
|
159
|
-
end
|
160
|
-
end
|
161
|
-
true
|
162
|
-
end
|
163
|
-
|
164
|
-
def check_matcher_matches
|
165
|
-
regex = schema[:matcher]
|
166
|
-
return unless regex
|
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
|
-
internals = schema[:internals]
|
196
|
-
# if there are no parameters specified, then assume all are ok.
|
197
|
-
return true unless internals
|
198
|
-
return true if schema[:permit_unknown_parameters]
|
199
|
-
data.keys.each do |k|
|
200
|
-
@errors << "#{key}: parameter '#{k}' is invalid" unless internals[k]
|
201
|
-
end
|
202
267
|
end
|
203
268
|
end
|
204
269
|
end
|
@@ -6,7 +6,7 @@ module Vcloud
|
|
6
6
|
|
7
7
|
def initialize(gateway_interface_hash)
|
8
8
|
if gateway_interface_hash.nil?
|
9
|
-
raise "EdgeGatewayInterface: gateway_interface_hash cannot be nil"
|
9
|
+
raise "EdgeGatewayInterface: gateway_interface_hash cannot be nil"
|
10
10
|
end
|
11
11
|
unless gateway_interface_hash[:Name] && gateway_interface_hash[:Network]
|
12
12
|
raise "EdgeGatewayInterface: bad input: #{gateway_interface_hash}"
|
@@ -33,11 +33,11 @@ module Vcloud
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
def self.get
|
37
|
-
ids = self.get_ids_by_name_and_catalog(
|
36
|
+
def self.get vapp_template_name, catalog_name
|
37
|
+
ids = self.get_ids_by_name_and_catalog(vapp_template_name, catalog_name)
|
38
38
|
raise 'Could not find template vApp' if ids.size == 0
|
39
39
|
if ids.size > 1
|
40
|
-
raise "Template #{
|
40
|
+
raise "Template #{vapp_template_name} is not unique in catalog #{catalog_name}"
|
41
41
|
end
|
42
42
|
return self.new(ids.first)
|
43
43
|
end
|
data/lib/vcloud/core/version.rb
CHANGED
data/lib/vcloud/core/vm.rb
CHANGED
@@ -112,15 +112,21 @@ module Vcloud
|
|
112
112
|
Vcloud::Fog::ServiceInterface.new.put_guest_customization_section(id, name, interpolated_preamble)
|
113
113
|
end
|
114
114
|
|
115
|
-
def generate_preamble(script_path, script_post_processor,
|
116
|
-
|
115
|
+
def generate_preamble(script_path, script_post_processor, preamble_vars)
|
116
|
+
erb_vars = OpenStruct.new({
|
117
|
+
vapp_name: vapp_name,
|
118
|
+
vars: preamble_vars
|
119
|
+
})
|
120
|
+
erb_vars_binding_object = erb_vars.instance_eval { binding }
|
121
|
+
erb_output = interpolate_erb_file(script_path, erb_vars_binding_object)
|
117
122
|
if script_post_processor
|
118
|
-
|
119
|
-
|
123
|
+
post_process_erb_output(erb_output, script_post_processor) if script_post_processor
|
124
|
+
else
|
125
|
+
erb_output
|
120
126
|
end
|
121
|
-
script
|
122
127
|
end
|
123
128
|
|
129
|
+
|
124
130
|
def update_storage_profile storage_profile
|
125
131
|
storage_profile_href = get_storage_profile_href_by_name(storage_profile, @vapp.name)
|
126
132
|
Vcloud::Fog::ServiceInterface.new.put_vm(id, name, {
|
@@ -132,6 +138,18 @@ module Vcloud
|
|
132
138
|
end
|
133
139
|
|
134
140
|
private
|
141
|
+
|
142
|
+
def interpolate_erb_file(erb_file, binding_object)
|
143
|
+
ERB.new(File.read(File.expand_path(erb_file)), nil, '>-').result(binding_object)
|
144
|
+
end
|
145
|
+
|
146
|
+
def post_process_erb_output(data_to_process, post_processor_script)
|
147
|
+
# Open3.capture2, as we just need to return STDOUT of the post_processor_script
|
148
|
+
Open3.capture2(
|
149
|
+
File.expand_path(post_processor_script),
|
150
|
+
stdin_data: data_to_process).first
|
151
|
+
end
|
152
|
+
|
135
153
|
def virtual_hardware_section
|
136
154
|
vcloud_attributes[:'ovf:VirtualHardwareSection'][:'ovf:Item']
|
137
155
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
module Vcloud
|
2
2
|
module Fog
|
3
3
|
module ContentTypes
|
4
|
-
CATALOG = 'application/vnd.vmware.vcloud.catalog+xml'
|
5
4
|
ORG = 'application/vnd.vmware.vcloud.org+xml'
|
6
5
|
VDC = 'application/vnd.vmware.vcloud.vdc+xml'
|
7
|
-
CATALOG_ITEM = 'application/vnd.vmware.vcloud.catalogItem+xml'
|
8
6
|
NETWORK = 'application/vnd.vmware.vcloud.network+xml'
|
9
7
|
METADATA = 'application/vnd.vmware.vcloud.metadata.value+xml'
|
10
8
|
end
|
@@ -35,10 +35,6 @@ module Vcloud
|
|
35
35
|
@vcloud.get_vapps_in_lease_from_query(options).body
|
36
36
|
end
|
37
37
|
|
38
|
-
def get_catalog_item(id)
|
39
|
-
@vcloud.get_catalog_item(id).body
|
40
|
-
end
|
41
|
-
|
42
38
|
def post_instantiate_vapp_template(vdc, template, name, params)
|
43
39
|
Vcloud::Core.logger.debug("instantiating #{name} vapp in #{vdc[:name]}")
|
44
40
|
vapp = @vcloud.post_instantiate_vapp_template(extract_id(vdc), template, name, params).body
|
@@ -151,10 +147,6 @@ module Vcloud
|
|
151
147
|
@vcloud.process_task(task)
|
152
148
|
end
|
153
149
|
|
154
|
-
def get_catalog(id)
|
155
|
-
@vcloud.get_catalog(id).body
|
156
|
-
end
|
157
|
-
|
158
150
|
def put_vapp_metadata_value(id, k, v)
|
159
151
|
Vcloud::Core.logger.debug("putting metadata pair '#{k}'=>'#{v}' to #{id}")
|
160
152
|
# need to convert key to_s since Fog 0.17 borks on symbol key
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Running vCloud Core Integration Tests
|
2
|
+
|
3
|
+
## Prerequisites
|
4
|
+
|
5
|
+
- Access to a suitable vCloud Director organisation.
|
6
|
+
|
7
|
+
**NB** It is not safe to run them against an environment that is in use
|
8
|
+
(e.g. production, preview) as many of the tests clear down all config at
|
9
|
+
the beginning and/or end to ensure the environment is as the tests expect.
|
10
|
+
|
11
|
+
- A config file with the settings configured.
|
12
|
+
|
13
|
+
There is a [template file](spec/integration/vcloud_tools_testing_config.yaml.template) to
|
14
|
+
help with this. Copy the template file to `spec/integration/vcloud_tools_testing_config.yaml`
|
15
|
+
and update with parameters suitable for your environment.
|
16
|
+
|
17
|
+
- You need to include the set-up for your testing environment in your
|
18
|
+
[fog file](https://github.com/alphagov/vcloud-core#credentials).
|
19
|
+
|
20
|
+
- The tests use the [vCloud Tools Tester](http://rubygems.org/gems/vcloud-tools-tester) gem.
|
21
|
+
You do not need to install this, `bundler` will do this for you.
|
22
|
+
|
23
|
+
## Parameters
|
24
|
+
|
25
|
+
````
|
26
|
+
default: # This is the fog credential that refers to your testing environment, e.g. `test_credential`
|
27
|
+
vdc_1_name: # The name of a VDC
|
28
|
+
catalog: # A catalog
|
29
|
+
vapp_template: # A vApp Template within that catalog
|
30
|
+
network_1: # The name of the primary network
|
31
|
+
network_1_ip: # The IP address of the primary network
|
32
|
+
````
|
33
|
+
|
34
|
+
## To run the tests
|
35
|
+
|
36
|
+
`FOG_CREDENTIAL=test_credential bundle exec integration`
|
@@ -4,28 +4,12 @@ module Vcloud
|
|
4
4
|
module Core
|
5
5
|
describe QueryRunner do
|
6
6
|
|
7
|
-
required_env = {
|
8
|
-
'VCLOUD_VDC_NAME' =>
|
9
|
-
'to the name of an orgVdc to use to instantiate vApps into',
|
10
|
-
'VCLOUD_TEMPLATE_NAME' =>
|
11
|
-
'to the name of a vAppTemplate to use create vApps in tests',
|
12
|
-
'VCLOUD_CATALOG_NAME' =>
|
13
|
-
'to the name of the catalog that VCLOUD_VAPP_TEMPLATE_NAME is stored in',
|
14
|
-
}
|
15
|
-
|
16
|
-
error = false
|
17
|
-
required_env.each do |var,message|
|
18
|
-
unless ENV[var]
|
19
|
-
puts "Must set #{var} #{message}" unless ENV[var]
|
20
|
-
error = true
|
21
|
-
end
|
22
|
-
end
|
23
|
-
Kernel.exit(2) if error
|
24
|
-
|
25
7
|
before(:all) do
|
26
|
-
|
27
|
-
|
28
|
-
@
|
8
|
+
config_file = File.join(File.dirname(__FILE__), "../vcloud_tools_testing_config.yaml")
|
9
|
+
test_data = Vcloud::Tools::Tester::TestParameters.new(config_file)
|
10
|
+
@vapp_template_name = test_data.vapp_template
|
11
|
+
@vapp_template_catalog_name = test_data.catalog
|
12
|
+
@vdc_name = test_data.vdc_1_name
|
29
13
|
end
|
30
14
|
|
31
15
|
context "#available_query_types" do
|
@@ -92,11 +76,13 @@ module Vcloud
|
|
92
76
|
|
93
77
|
before(:all) do
|
94
78
|
@number_of_vapps_to_create = 2
|
95
|
-
@test_case_vapps = create_test_case_vapps(
|
79
|
+
@test_case_vapps = IntegrationHelper.create_test_case_vapps(
|
96
80
|
@number_of_vapps_to_create,
|
97
81
|
@vdc_name,
|
98
82
|
@vapp_template_catalog_name,
|
99
83
|
@vapp_template_name,
|
84
|
+
[],
|
85
|
+
"vcloud-core-query-tests"
|
100
86
|
)
|
101
87
|
end
|
102
88
|
|
@@ -194,27 +180,7 @@ module Vcloud
|
|
194
180
|
end
|
195
181
|
|
196
182
|
after(:all) do
|
197
|
-
|
198
|
-
@test_case_vapps.each do |vapp|
|
199
|
-
fsi.delete_vapp(vapp.id)
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
def create_test_case_vapps(quantity, vdc_name, catalog_name, vapp_template_name)
|
204
|
-
vapp_template = VappTemplate.get(catalog_name, vapp_template_name)
|
205
|
-
timestamp_in_s = Time.new.to_i
|
206
|
-
base_vapp_name = "vcloud-core-query-tests-#{timestamp_in_s}-"
|
207
|
-
network_names = []
|
208
|
-
vapp_list = []
|
209
|
-
quantity.times do |index|
|
210
|
-
vapp_list << Vapp.instantiate(
|
211
|
-
base_vapp_name + index.to_s,
|
212
|
-
network_names,
|
213
|
-
vapp_template.id,
|
214
|
-
vdc_name
|
215
|
-
)
|
216
|
-
end
|
217
|
-
vapp_list
|
183
|
+
IntegrationHelper.delete_vapps(@test_case_vapps)
|
218
184
|
end
|
219
185
|
|
220
186
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -14,15 +14,17 @@ end
|
|
14
14
|
|
15
15
|
require 'bundler/setup'
|
16
16
|
require 'vcloud/core'
|
17
|
+
require 'vcloud/tools/tester'
|
17
18
|
require 'support/stub_fog_interface.rb'
|
19
|
+
require 'support/integration_helper'
|
18
20
|
|
19
21
|
if ENV['COVERAGE']
|
20
22
|
SimpleCov.at_exit do
|
21
23
|
SimpleCov.result.format!
|
22
24
|
# do not change the coverage percentage, instead add more unit tests to fix coverage failures.
|
23
|
-
if SimpleCov.result.covered_percent <
|
25
|
+
if SimpleCov.result.covered_percent < 81
|
24
26
|
print "ERROR::BAD_COVERAGE\n"
|
25
|
-
print "Coverage is less than acceptable limit(
|
27
|
+
print "Coverage is less than acceptable limit(81%). Please add more tests to improve the coverage"
|
26
28
|
exit(1)
|
27
29
|
end
|
28
30
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module IntegrationHelper
|
2
|
+
|
3
|
+
def self.create_test_case_vapps(number_of_vapps,
|
4
|
+
vdc_name,
|
5
|
+
catalog_name,
|
6
|
+
vapp_template_name,
|
7
|
+
network_names = [],
|
8
|
+
prefix = "vcloud-core-tests"
|
9
|
+
)
|
10
|
+
vapp_template = Vcloud::Core::VappTemplate.get(vapp_template_name, catalog_name)
|
11
|
+
timestamp_in_s = Time.new.to_i
|
12
|
+
base_vapp_name = "#{prefix}-#{timestamp_in_s}-"
|
13
|
+
vapp_list = []
|
14
|
+
number_of_vapps.times do |index|
|
15
|
+
vapp_list << Vcloud::Core::Vapp.instantiate(
|
16
|
+
base_vapp_name + index.to_s,
|
17
|
+
network_names,
|
18
|
+
vapp_template.id,
|
19
|
+
vdc_name
|
20
|
+
)
|
21
|
+
end
|
22
|
+
vapp_list
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.delete_vapps(vapp_list)
|
26
|
+
fsi = Vcloud::Fog::ServiceInterface.new()
|
27
|
+
vapp_list.each do |vapp|
|
28
|
+
fsi.delete_vapp(vapp.id)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -57,6 +57,32 @@ module Vcloud
|
|
57
57
|
expect { loader.load_config(input_file, invalid_schema) }.
|
58
58
|
to raise_error('Supplied configuration does not match supplied schema')
|
59
59
|
end
|
60
|
+
|
61
|
+
it "should not log warnings if there are none" do
|
62
|
+
input_file = "#{@data_dir}/working_with_defaults.yaml"
|
63
|
+
loader = ConfigLoader.new
|
64
|
+
|
65
|
+
Vcloud::Core.logger.should_not_receive(:warn)
|
66
|
+
loader.load_config(input_file, vapp_config_schema)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should log warnings if checked against a deprecated schema" do
|
70
|
+
input_file = "#{@data_dir}/working_with_defaults.yaml"
|
71
|
+
loader = ConfigLoader.new
|
72
|
+
|
73
|
+
Vcloud::Core.logger.should_receive(:warn).with("vapps: is deprecated by 'vapps_new'")
|
74
|
+
loader.load_config(input_file, deprecated_schema)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should log warning before raising error against an invalid and deprecated schema" do
|
78
|
+
input_file = "#{@data_dir}/working_with_defaults.yaml"
|
79
|
+
loader = ConfigLoader.new
|
80
|
+
|
81
|
+
Vcloud::Core.logger.should_receive(:warn).with("vapps: is deprecated by 'vapps_new'")
|
82
|
+
Vcloud::Core.logger.should_receive(:fatal).with("vapps: is not a hash")
|
83
|
+
expect { loader.load_config(input_file, invalid_and_deprecated_schema) }.
|
84
|
+
to raise_error('Supplied configuration does not match supplied schema')
|
85
|
+
end
|
60
86
|
end
|
61
87
|
|
62
88
|
def vapp_config_schema
|
@@ -84,13 +110,35 @@ module Vcloud
|
|
84
110
|
}
|
85
111
|
end
|
86
112
|
|
113
|
+
def invalid_and_deprecated_schema
|
114
|
+
{
|
115
|
+
type: 'hash',
|
116
|
+
permit_unknown_parameters: true,
|
117
|
+
internals: {
|
118
|
+
vapps: { type: Hash, deprecated_by: 'vapps_new' },
|
119
|
+
vapps_new: { type: 'array' },
|
120
|
+
}
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
def deprecated_schema
|
125
|
+
{
|
126
|
+
type: 'hash',
|
127
|
+
permit_unknown_parameters: true,
|
128
|
+
internals: {
|
129
|
+
vapps: { type: 'array', deprecated_by: 'vapps_new' },
|
130
|
+
vapps_new: { type: 'array' },
|
131
|
+
}
|
132
|
+
}
|
133
|
+
end
|
134
|
+
|
87
135
|
def valid_config
|
88
136
|
{
|
89
137
|
:vapps=>[{
|
90
138
|
:name=>"vapp-vcloud-tools-tests",
|
91
139
|
:vdc_name=>"VDC_NAME",
|
92
140
|
:catalog=>"CATALOG_NAME",
|
93
|
-
:
|
141
|
+
:vapp_template=>"VAPP_TEMPLATE",
|
94
142
|
:vm=>{
|
95
143
|
:hardware_config=>{:memory=>"4096", :cpu=>"2"},
|
96
144
|
:extra_disks=>[{:size=>"8192"}],
|
@@ -564,7 +564,125 @@ module Vcloud
|
|
564
564
|
expect(v.valid?).to be_true
|
565
565
|
end
|
566
566
|
end
|
567
|
+
end
|
568
|
+
|
569
|
+
context "deprecated_by" do
|
570
|
+
# For clarification:
|
571
|
+
#
|
572
|
+
# - deprecatee: is the old param with a `deprecated_by` field.
|
573
|
+
# - deprecator: is the new param listed in the `deprecated_by` field.
|
574
|
+
#
|
575
|
+
context "deprecatee is provided and deprecator is not" do
|
576
|
+
let(:data) {{ name: "santa" }}
|
577
|
+
|
578
|
+
it "should validate and warn when deprecator is required" do
|
579
|
+
schema = {
|
580
|
+
type: "Hash",
|
581
|
+
internals: {
|
582
|
+
name: { type: 'string', deprecated_by: 'full_name' },
|
583
|
+
full_name: { type: 'string', required: true },
|
584
|
+
}
|
585
|
+
}
|
586
|
+
v = ConfigValidator.validate(:base, data, schema)
|
587
|
+
expect(v.valid?).to be_true
|
588
|
+
expect(v.warnings).to eq(["name: is deprecated by 'full_name'"])
|
589
|
+
end
|
590
|
+
|
591
|
+
it "should validate and warn when deprecator appears before deprecatee in schema" do
|
592
|
+
schema = {
|
593
|
+
type: "Hash",
|
594
|
+
internals: {
|
595
|
+
full_name: { type: 'string', required: true },
|
596
|
+
name: { type: 'string', deprecated_by: 'full_name' },
|
597
|
+
}
|
598
|
+
}
|
599
|
+
v = ConfigValidator.validate(:base, data, schema)
|
600
|
+
expect(v.valid?).to be_true
|
601
|
+
expect(v.warnings).to eq(["name: is deprecated by 'full_name'"])
|
602
|
+
end
|
603
|
+
|
604
|
+
it "should warn about deprecatee even when both are not required" do
|
605
|
+
schema = {
|
606
|
+
type: "Hash",
|
607
|
+
internals: {
|
608
|
+
name: { type: 'string', required: false, deprecated_by: 'full_name' },
|
609
|
+
full_name: { type: 'string', required: false },
|
610
|
+
}
|
611
|
+
}
|
612
|
+
v = ConfigValidator.validate(:base, data, schema)
|
613
|
+
expect(v.valid?).to be_true
|
614
|
+
expect(v.warnings).to eq(["name: is deprecated by 'full_name'"])
|
615
|
+
end
|
616
|
+
end
|
617
|
+
|
618
|
+
context "neither deprecatee or deprecator are provided" do
|
619
|
+
let(:data) {{ bogus: "blah" }}
|
620
|
+
|
621
|
+
it "should return error for deprecator but not deprecatee if neither are set" do
|
622
|
+
schema = {
|
623
|
+
type: "Hash",
|
624
|
+
internals: {
|
625
|
+
name: { type: 'string', deprecated_by: 'full_name' },
|
626
|
+
full_name: { type: 'string', required: true },
|
627
|
+
bogus: { type: 'string' },
|
628
|
+
}
|
629
|
+
}
|
630
|
+
v = ConfigValidator.validate(:base, data, schema)
|
631
|
+
expect(v.valid?).to be_false
|
632
|
+
expect(v.errors).to eq(["base: missing 'full_name' parameter"])
|
633
|
+
end
|
634
|
+
|
635
|
+
it "should raise exception if deprecator does not exist in schema" do
|
636
|
+
schema = {
|
637
|
+
type: "Hash",
|
638
|
+
internals: {
|
639
|
+
name: { type: 'string', deprecated_by: 'does_not_exist' },
|
640
|
+
bogus: { type: 'string' },
|
641
|
+
}
|
642
|
+
}
|
643
|
+
expect {
|
644
|
+
ConfigValidator.validate(:base, data, schema)
|
645
|
+
}.to raise_error("name: deprecated_by target 'does_not_exist' not found in schema")
|
646
|
+
end
|
647
|
+
end
|
648
|
+
|
649
|
+
context "deprecatee and deprecator are provided and of the wrong type" do
|
650
|
+
let(:data) {{ name: 123, full_name: 123 }}
|
651
|
+
|
652
|
+
it "should return an error for each and a warning for deprecatee" do
|
653
|
+
schema = {
|
654
|
+
type: "Hash",
|
655
|
+
internals: {
|
656
|
+
name: { type: 'string', deprecated_by: 'full_name' },
|
657
|
+
full_name: { type: 'string', required: true },
|
658
|
+
}
|
659
|
+
}
|
660
|
+
v = ConfigValidator.validate(:base, data, schema)
|
661
|
+
expect(v.valid?).to be_false
|
662
|
+
expect(v.errors).to eq([
|
663
|
+
"name: 123 is not a string",
|
664
|
+
"full_name: 123 is not a string",
|
665
|
+
])
|
666
|
+
expect(v.warnings).to eq(["name: is deprecated by 'full_name'"])
|
667
|
+
end
|
668
|
+
end
|
567
669
|
|
670
|
+
it "should not honour deprecation across nested structures" do
|
671
|
+
data = { bogus: "blah" }
|
672
|
+
schema = {
|
673
|
+
type: "Hash",
|
674
|
+
internals: {
|
675
|
+
name: { type: 'string', deprecated_by: 'full_name' },
|
676
|
+
nested: { type: 'hash', internals: {
|
677
|
+
full_name: { type: 'string', required: true },
|
678
|
+
}},
|
679
|
+
bogus: { type: 'string' },
|
680
|
+
}
|
681
|
+
}
|
682
|
+
expect {
|
683
|
+
ConfigValidator.validate(:base, data, schema)
|
684
|
+
}.to raise_error("name: deprecated_by target 'full_name' not found in schema")
|
685
|
+
end
|
568
686
|
end
|
569
687
|
|
570
688
|
end
|
@@ -4,6 +4,10 @@
|
|
4
4
|
|
5
5
|
(
|
6
6
|
echo "in $*"
|
7
|
+
echo "env_var: <%= ENV['TEST_INTERPOLATED_ENVVAR'] -%>"
|
7
8
|
echo "vapp_name: <%= vapp_name -%>"
|
8
9
|
echo "message: <%= vars[:message] -%>"
|
10
|
+
<% vars[:array_test].each_with_index do |element, index| -%>
|
11
|
+
echo "index<%= index -%>: <%= element -%>"
|
12
|
+
<% end -%>
|
9
13
|
) >> /PREAMBLE_OUTPUT
|
@@ -8,10 +8,6 @@ module Vcloud
|
|
8
8
|
@id = 'vappTemplate-12345678-1234-1234-1234-000000234121'
|
9
9
|
@mock_fog_interface = StubFogInterface.new
|
10
10
|
Vcloud::Fog::ServiceInterface.stub(:new).and_return(@mock_fog_interface)
|
11
|
-
@test_config = {
|
12
|
-
:catalog => 'test_catalog',
|
13
|
-
:catalog_item => 'test_template'
|
14
|
-
}
|
15
11
|
end
|
16
12
|
|
17
13
|
context "Class public interface" do
|
@@ -55,7 +51,7 @@ module Vcloud
|
|
55
51
|
mock_query.should_receive(:run).
|
56
52
|
with('vAppTemplate', :filter => "name==test_template;catalogName==test_catalog").
|
57
53
|
and_return(q_results)
|
58
|
-
expect { VappTemplate.get('
|
54
|
+
expect { VappTemplate.get('test_template', 'test_catalog') }.
|
59
55
|
to raise_error('Could not find template vApp')
|
60
56
|
end
|
61
57
|
|
@@ -71,7 +67,7 @@ module Vcloud
|
|
71
67
|
mock_query.should_receive(:run).
|
72
68
|
with('vAppTemplate', :filter => "name==test_template;catalogName==test_catalog").
|
73
69
|
and_return(q_results)
|
74
|
-
expect { VappTemplate.get('
|
70
|
+
expect { VappTemplate.get('test_template', 'test_catalog') }.
|
75
71
|
to raise_error('Template test_template is not unique in catalog test_catalog')
|
76
72
|
end
|
77
73
|
|
@@ -85,7 +81,7 @@ module Vcloud
|
|
85
81
|
mock_query.should_receive(:run).
|
86
82
|
with('vAppTemplate', :filter => "name==test_template;catalogName==test_catalog").
|
87
83
|
and_return(q_results)
|
88
|
-
test_template = VappTemplate.get('
|
84
|
+
test_template = VappTemplate.get('test_template', 'test_catalog')
|
89
85
|
test_template.id.should == 'vappTemplate-12345678-90ab-cdef-0123-4567890abcde'
|
90
86
|
end
|
91
87
|
|
data/spec/vcloud/core/vm_spec.rb
CHANGED
@@ -181,18 +181,26 @@ module Vcloud
|
|
181
181
|
end
|
182
182
|
|
183
183
|
context '#generate_preamble' do
|
184
|
-
it "should interpolate vars hash and vapp_name into template" do
|
185
|
-
vars = {
|
184
|
+
it "should interpolate vars hash, ENV, and vapp_name into template" do
|
185
|
+
vars = {
|
186
|
+
:message => 'hello world',
|
187
|
+
:array_test => [ 'foo', 'bar' ],
|
188
|
+
}
|
189
|
+
stub_const('ENV', {'TEST_INTERPOLATED_ENVVAR' => 'test_interpolated_env'})
|
186
190
|
erbfile = "#{@data_dir}/basic_preamble_test.erb"
|
187
191
|
expected_output = File.read("#{erbfile}.OUT")
|
188
192
|
@vm.generate_preamble(erbfile, nil, vars).should == expected_output
|
189
193
|
end
|
190
194
|
|
191
|
-
it "
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
195
|
+
it "passes the output of ERB through an optional post-processor tool" do
|
196
|
+
# we use 'wc' as post processor since it will give us the character
|
197
|
+
# count in the file, which we can easily match on, and is common
|
198
|
+
# across most OSes.
|
199
|
+
vars = {}
|
200
|
+
erbfile = "#{@data_dir}/preamble_post_processor_test_input.erb"
|
201
|
+
characters_in_file = File.read(erbfile).size
|
202
|
+
expect(@vm.generate_preamble(erbfile, '/usr/bin/wc', vars)).
|
203
|
+
to match(/^\s+\d+\s+\d+\s+#{characters_in_file}\s/)
|
196
204
|
end
|
197
205
|
end
|
198
206
|
|
data/vcloud-core.gemspec
CHANGED
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.
|
4
|
+
version: 0.4.0
|
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-05-
|
12
|
+
date: 2014-05-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fog
|
@@ -171,6 +171,22 @@ dependencies:
|
|
171
171
|
- - '='
|
172
172
|
- !ruby/object:Gem::Version
|
173
173
|
version: 1.2.0
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: vcloud-tools-tester
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - '='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: 0.0.3
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - '='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: 0.0.3
|
174
190
|
description: Core tools for interacting with VMware vCloud Director. Includes VCloud
|
175
191
|
Query, a light wrapper round the vCloud Query API.
|
176
192
|
email:
|
@@ -213,15 +229,19 @@ files:
|
|
213
229
|
- lib/vcloud/fog/model_interface.rb
|
214
230
|
- lib/vcloud/fog/relation.rb
|
215
231
|
- lib/vcloud/fog/service_interface.rb
|
232
|
+
- spec/integration/README.md
|
233
|
+
- spec/integration/core/query_runner_spec.rb
|
216
234
|
- spec/integration/edge_gateway/configure_edge_gateway_services_spec.rb
|
217
235
|
- spec/integration/edge_gateway/edge_gateway_spec.rb
|
218
|
-
- spec/integration/
|
236
|
+
- spec/integration/vcloud_tools_testing_config.yaml.template
|
219
237
|
- spec/spec_helper.rb
|
238
|
+
- spec/support/integration_helper.rb
|
220
239
|
- spec/support/stub_fog_interface.rb
|
221
240
|
- spec/vcloud/core/config_loader_spec.rb
|
222
241
|
- spec/vcloud/core/config_validator_spec.rb
|
223
242
|
- spec/vcloud/core/data/basic_preamble_test.erb
|
224
243
|
- spec/vcloud/core/data/basic_preamble_test.erb.OUT
|
244
|
+
- spec/vcloud/core/data/preamble_post_processor_test_input.erb
|
225
245
|
- spec/vcloud/core/data/working.json
|
226
246
|
- spec/vcloud/core/data/working.yaml
|
227
247
|
- spec/vcloud/core/data/working_template.yaml
|
@@ -262,7 +282,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
262
282
|
version: '0'
|
263
283
|
segments:
|
264
284
|
- 0
|
265
|
-
hash:
|
285
|
+
hash: -2177023225627992680
|
266
286
|
requirements: []
|
267
287
|
rubyforge_project:
|
268
288
|
rubygems_version: 1.8.23
|
@@ -272,15 +292,19 @@ summary: Core tools for interacting with VMware vCloud Director
|
|
272
292
|
test_files:
|
273
293
|
- features/support/env.rb
|
274
294
|
- features/vcloud-query.feature
|
295
|
+
- spec/integration/README.md
|
296
|
+
- spec/integration/core/query_runner_spec.rb
|
275
297
|
- spec/integration/edge_gateway/configure_edge_gateway_services_spec.rb
|
276
298
|
- spec/integration/edge_gateway/edge_gateway_spec.rb
|
277
|
-
- spec/integration/
|
299
|
+
- spec/integration/vcloud_tools_testing_config.yaml.template
|
278
300
|
- spec/spec_helper.rb
|
301
|
+
- spec/support/integration_helper.rb
|
279
302
|
- spec/support/stub_fog_interface.rb
|
280
303
|
- spec/vcloud/core/config_loader_spec.rb
|
281
304
|
- spec/vcloud/core/config_validator_spec.rb
|
282
305
|
- spec/vcloud/core/data/basic_preamble_test.erb
|
283
306
|
- spec/vcloud/core/data/basic_preamble_test.erb.OUT
|
307
|
+
- spec/vcloud/core/data/preamble_post_processor_test_input.erb
|
284
308
|
- spec/vcloud/core/data/working.json
|
285
309
|
- spec/vcloud/core/data/working.yaml
|
286
310
|
- spec/vcloud/core/data/working_template.yaml
|