vcloud-edge_gateway 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/.gitignore +16 -0
  2. data/Gemfile +9 -0
  3. data/LICENSE.txt +20 -0
  4. data/README.md +160 -0
  5. data/Rakefile +23 -0
  6. data/bin/vcloud-edge +12 -0
  7. data/jenkins.sh +11 -0
  8. data/lib/vcloud/config_loader.rb +27 -0
  9. data/lib/vcloud/config_validator.rb +207 -0
  10. data/lib/vcloud/edge_gateway/configuration_differ.rb +17 -0
  11. data/lib/vcloud/edge_gateway/configuration_generator/firewall_service.rb +63 -0
  12. data/lib/vcloud/edge_gateway/configuration_generator/id_ranges.rb +10 -0
  13. data/lib/vcloud/edge_gateway/configuration_generator/load_balancer_service.rb +243 -0
  14. data/lib/vcloud/edge_gateway/configuration_generator/nat_service.rb +54 -0
  15. data/lib/vcloud/edge_gateway/edge_gateway_configuration.rb +41 -0
  16. data/lib/vcloud/edge_gateway/version.rb +6 -0
  17. data/lib/vcloud/edge_gateway.rb +32 -0
  18. data/lib/vcloud/edge_gateway_services.rb +26 -0
  19. data/lib/vcloud/schema/edge_gateway.rb +15 -0
  20. data/lib/vcloud/schema/firewall_service.rb +39 -0
  21. data/lib/vcloud/schema/load_balancer_service.rb +129 -0
  22. data/lib/vcloud/schema/nat_service.rb +35 -0
  23. data/scripts/generate_fog_conf_file.sh +6 -0
  24. data/spec/erb_helper.rb +11 -0
  25. data/spec/integration/edge_gateway/data/firewall_config.yaml.erb +17 -0
  26. data/spec/integration/edge_gateway/data/firewall_config_updated_rule.yaml.erb +17 -0
  27. data/spec/integration/edge_gateway/data/firewall_rule_order_test.yaml.erb +24 -0
  28. data/spec/integration/edge_gateway/data/hairpin_nat_config.yaml.erb +13 -0
  29. data/spec/integration/edge_gateway/data/incorrect_firewall_config.yaml +14 -0
  30. data/spec/integration/edge_gateway/data/nat_and_firewall_config.yaml.erb +32 -0
  31. data/spec/integration/edge_gateway/data/nat_config.yaml.erb +17 -0
  32. data/spec/integration/edge_gateway/edge_gateway_services_spec.rb +132 -0
  33. data/spec/integration/edge_gateway/firewall_service_spec.rb +201 -0
  34. data/spec/integration/edge_gateway/nat_service_spec.rb +208 -0
  35. data/spec/spec_helper.rb +26 -0
  36. data/spec/vcloud/config_loader_spec.rb +112 -0
  37. data/spec/vcloud/config_validator_spec.rb +570 -0
  38. data/spec/vcloud/data/basic_preamble_test.erb +8 -0
  39. data/spec/vcloud/data/basic_preamble_test.erb.OUT +8 -0
  40. data/spec/vcloud/data/working.json +21 -0
  41. data/spec/vcloud/data/working.yaml +22 -0
  42. data/spec/vcloud/data/working_with_defaults.yaml +25 -0
  43. data/spec/vcloud/edge_gateway/configuration_differ_spec.rb +131 -0
  44. data/spec/vcloud/edge_gateway/configuration_generator/data/load_balancer_http-input.yaml +41 -0
  45. data/spec/vcloud/edge_gateway/configuration_generator/data/load_balancer_http-output.yaml +93 -0
  46. data/spec/vcloud/edge_gateway/configuration_generator/data/load_balancer_https-input.yaml +39 -0
  47. data/spec/vcloud/edge_gateway/configuration_generator/data/load_balancer_https-output.yaml +92 -0
  48. data/spec/vcloud/edge_gateway/configuration_generator/data/load_balancer_mixed_complex-input.yaml +65 -0
  49. data/spec/vcloud/edge_gateway/configuration_generator/data/load_balancer_mixed_complex-output.yaml +94 -0
  50. data/spec/vcloud/edge_gateway/configuration_generator/firewall_service_spec.rb +378 -0
  51. data/spec/vcloud/edge_gateway/configuration_generator/load_balancer_service_spec.rb +233 -0
  52. data/spec/vcloud/edge_gateway/configuration_generator/nat_service_spec.rb +360 -0
  53. data/spec/vcloud/edge_gateway/edge_gateway_configuration_spec.rb +182 -0
  54. data/spec/vcloud/edge_gateway/firewall_schema_validation_spec.rb +45 -0
  55. data/spec/vcloud/edge_gateway/load_balancer_schema_validation_spec.rb +153 -0
  56. data/spec/vcloud/edge_gateway/nat_schema_validation_spec.rb +93 -0
  57. data/vcloud-edge_gateway.gemspec +32 -0
  58. metadata +252 -0
@@ -0,0 +1,360 @@
1
+ require 'spec_helper'
2
+
3
+ module Vcloud
4
+ module EdgeGateway
5
+ module ConfigurationGenerator
6
+ describe NatService do
7
+
8
+ before(:each) do
9
+ @edge_id = '1111111-7b54-43dd-9eb1-631dd337e5a7'
10
+ @mock_edge_gateway = double(
11
+ :edge_gateway,
12
+ :vcloud_gateway_interface_by_id => {
13
+ Network: {
14
+ name: 'ane012345',
15
+ href: 'https://vmware.api.net/api/admin/network/2ad93597-7b54-43dd-9eb1-631dd337e5a7'
16
+ }
17
+ }
18
+ )
19
+ expect(Vcloud::Core::EdgeGateway).to receive(:get_by_name).with(@edge_id)
20
+ .and_return(@mock_edge_gateway)
21
+ end
22
+
23
+ context "SNAT rule defaults" do
24
+
25
+ before(:each) do
26
+ input = { nat_rules: [{
27
+ rule_type: 'SNAT',
28
+ network_id: '2ad93597-7b54-43dd-9eb1-631dd337e5a7',
29
+ original_ip: "192.0.2.2",
30
+ translated_ip: "10.10.20.20",
31
+ }]} # minimum NAT configuration with a rule
32
+ output = NatService.new(@edge_id, input).generate_fog_config
33
+ @rule = output[:NatRule].first
34
+ end
35
+
36
+ it 'should default to the rule being enabled' do
37
+ expect(@rule[:IsEnabled]).to eq('true')
38
+ end
39
+
40
+ it 'should have a RuleType of SNAT' do
41
+ expect(@rule[:RuleType]).to eq('SNAT')
42
+ end
43
+
44
+ it 'should not include a Protocol' do
45
+ expect(@rule[:GatewayNatRule].key?(:Protocol)).to be_false
46
+ end
47
+
48
+ it 'should completely match our expected default rule' do
49
+ expect(@rule).to eq({
50
+ :Id=>"65537",
51
+ :IsEnabled=>"true",
52
+ :RuleType=>"SNAT",
53
+ :GatewayNatRule=>{
54
+ :Interface=>{
55
+ :name=>"ane012345",
56
+ :href=>"https://vmware.api.net/api/admin/network/2ad93597-7b54-43dd-9eb1-631dd337e5a7"
57
+ },
58
+ :OriginalIp=>"192.0.2.2",
59
+ :TranslatedIp=>"10.10.20.20"}
60
+ })
61
+ end
62
+
63
+ end
64
+
65
+ context "DNAT rule defaults" do
66
+
67
+ before(:each) do
68
+ input = { nat_rules: [{
69
+ rule_type: 'DNAT',
70
+ network_id: '2ad93597-7b54-43dd-9eb1-631dd337e5a7',
71
+ original_ip: "192.0.2.2",
72
+ original_port: '22',
73
+ translated_port: '22',
74
+ translated_ip: "10.10.20.20",
75
+ protocol: 'tcp',
76
+ }]} # minimum NAT configuration with a rule
77
+ output = NatService.new(@edge_id, input).generate_fog_config
78
+ @rule = output[:NatRule].first
79
+ end
80
+
81
+ it 'should default to rule being enabled' do
82
+ expect(@rule[:IsEnabled]).to eq('true')
83
+ end
84
+
85
+ it 'should have a RuleType of DNAT' do
86
+ expect(@rule[:RuleType]).to eq('DNAT')
87
+ end
88
+
89
+ it 'should include a default Protocol of tcp' do
90
+ expect(@rule[:GatewayNatRule][:Protocol]).to eq('tcp')
91
+ end
92
+
93
+ it 'should completely match our expected default rule' do
94
+ expect(@rule).to eq({
95
+ :Id=>"65537",
96
+ :IsEnabled=>"true",
97
+ :RuleType=>"DNAT",
98
+ :GatewayNatRule=>{
99
+ :Interface=>{
100
+ :name=>"ane012345",
101
+ :href=>"https://vmware.api.net/api/admin/network/2ad93597-7b54-43dd-9eb1-631dd337e5a7"
102
+ },
103
+ :OriginalIp=>"192.0.2.2",
104
+ :TranslatedIp=>"10.10.20.20",
105
+ :OriginalPort=>"22",
106
+ :TranslatedPort=>"22",
107
+ :Protocol=>"tcp"
108
+ }
109
+ })
110
+ end
111
+
112
+ end
113
+
114
+ context "nat service config generation" do
115
+
116
+ test_cases = [
117
+ {
118
+ title: 'should generate config for enabled nat service with single disabled DNAT rule',
119
+ input: {
120
+ enabled: 'true',
121
+ nat_rules: [
122
+ {
123
+ enabled: 'false',
124
+ id: '999',
125
+ rule_type: 'DNAT',
126
+ network_id: '2ad93597-7b54-43dd-9eb1-631dd337e5a7',
127
+ original_ip: "192.0.2.2",
128
+ original_port: '22',
129
+ translated_port: '22',
130
+ translated_ip: "10.10.20.20",
131
+ protocol: 'tcp',
132
+ }
133
+ ]
134
+ },
135
+ output: {
136
+ :IsEnabled => 'true',
137
+ :NatRule => [
138
+ {
139
+ :RuleType => 'DNAT',
140
+ :IsEnabled => 'false',
141
+ :Id => '999',
142
+ :GatewayNatRule => {
143
+ :Interface =>
144
+ {
145
+ :name => 'ane012345',
146
+ :href => 'https://vmware.api.net/api/admin/network/2ad93597-7b54-43dd-9eb1-631dd337e5a7'
147
+ },
148
+ :Protocol => 'tcp',
149
+ :OriginalIp => "192.0.2.2",
150
+ :OriginalPort => '22',
151
+ :TranslatedIp => "10.10.20.20",
152
+ :TranslatedPort => '22'
153
+ }
154
+ }
155
+ ]
156
+ }
157
+ },
158
+
159
+ {
160
+ title: 'should handle specification of UDP based DNAT rules',
161
+ input: {
162
+ enabled: 'true',
163
+ nat_rules: [
164
+ {
165
+ rule_type: 'DNAT',
166
+ network_id: '2ad93597-7b54-43dd-9eb1-631dd337e5a7',
167
+ original_ip: "192.0.2.25",
168
+ original_port: '53',
169
+ translated_port: '53',
170
+ translated_ip: "10.10.20.25",
171
+ protocol: 'udp',
172
+ }
173
+ ]
174
+ },
175
+ output: {
176
+ :IsEnabled => 'true',
177
+ :NatRule => [
178
+ {
179
+ :RuleType => 'DNAT',
180
+ :IsEnabled => 'true',
181
+ :Id => '65537',
182
+ :GatewayNatRule => {
183
+ :Interface =>
184
+ {
185
+ :name => 'ane012345',
186
+ :href => 'https://vmware.api.net/api/admin/network/2ad93597-7b54-43dd-9eb1-631dd337e5a7'
187
+ },
188
+ :Protocol => 'udp',
189
+ :OriginalIp => "192.0.2.25",
190
+ :OriginalPort => '53',
191
+ :TranslatedIp => "10.10.20.25",
192
+ :TranslatedPort => '53'
193
+ }
194
+ }
195
+ ]
196
+ }
197
+ },
198
+
199
+ {
200
+ title: 'should generate config for enabled nat service with single disabled SNAT rule',
201
+ input: {
202
+ enabled: 'true',
203
+ nat_rules: [
204
+ {
205
+ enabled: 'false',
206
+ rule_type: 'SNAT',
207
+ network_id: '2ad93597-7b54-43dd-9eb1-631dd337e5a7',
208
+ original_ip: "192.0.2.2",
209
+ translated_ip: "10.10.20.20",
210
+ }
211
+ ]
212
+ },
213
+ output: {
214
+ :IsEnabled => 'true',
215
+ :NatRule => [
216
+ {
217
+ :RuleType => 'SNAT',
218
+ :IsEnabled => 'false',
219
+ :Id => '65537',
220
+ :GatewayNatRule => {
221
+ :Interface =>
222
+ {
223
+ :name => 'ane012345',
224
+ :href => 'https://vmware.api.net/api/admin/network/2ad93597-7b54-43dd-9eb1-631dd337e5a7'
225
+ },
226
+ :OriginalIp => "192.0.2.2",
227
+ :TranslatedIp => "10.10.20.20",
228
+ }
229
+ }
230
+ ]
231
+ }
232
+ },
233
+
234
+ {
235
+ title: 'should auto generate rule id if not provided',
236
+ input: {
237
+ enabled: 'true',
238
+ nat_rules: [
239
+ {
240
+ enabled: 'false',
241
+ rule_type: 'DNAT',
242
+ network_id: '2ad93597-7b54-43dd-9eb1-631dd337e5a7',
243
+ original_ip: "192.0.2.2",
244
+ original_port: '22',
245
+ translated_port: '22',
246
+ translated_ip: "10.10.20.20",
247
+ protocol: 'tcp',
248
+ }
249
+ ]
250
+ },
251
+ output: {
252
+ :IsEnabled => 'true',
253
+ :NatRule => [
254
+ {
255
+ :RuleType => 'DNAT',
256
+ :IsEnabled => 'false',
257
+ :Id => '65537',
258
+ :GatewayNatRule => {
259
+ :Interface =>
260
+ {
261
+ :name => 'ane012345',
262
+ :href => 'https://vmware.api.net/api/admin/network/2ad93597-7b54-43dd-9eb1-631dd337e5a7'
263
+ },
264
+ :Protocol => 'tcp',
265
+ :OriginalIp => "192.0.2.2",
266
+ :OriginalPort => '22',
267
+ :TranslatedIp => "10.10.20.20",
268
+ :TranslatedPort => '22'
269
+ }
270
+ }
271
+ ]
272
+ }
273
+ },
274
+
275
+ {
276
+ title: 'should use default values for optional fields if they are missing',
277
+ input: {
278
+ nat_rules: [
279
+ {
280
+ rule_type: 'DNAT',
281
+ network_id: '2ad93597-7b54-43dd-9eb1-631dd337e5a7',
282
+ original_ip: "192.0.2.2",
283
+ original_port: '22',
284
+ translated_port: '22',
285
+ translated_ip: "10.10.20.20",
286
+ }
287
+ ]
288
+ },
289
+ output: {
290
+ :IsEnabled => 'true',
291
+ :NatRule => [
292
+ {
293
+ :RuleType => 'DNAT',
294
+ :IsEnabled => 'true',
295
+ :Id => '65537',
296
+ :GatewayNatRule => {
297
+ :Interface =>
298
+ {
299
+ :name => 'ane012345',
300
+ :href => 'https://vmware.api.net/api/admin/network/2ad93597-7b54-43dd-9eb1-631dd337e5a7'
301
+ },
302
+ :Protocol => 'tcp',
303
+ :OriginalIp => "192.0.2.2",
304
+ :OriginalPort => '22',
305
+ :TranslatedIp => "10.10.20.20",
306
+ :TranslatedPort => '22'
307
+ }
308
+ }
309
+ ]
310
+ }
311
+
312
+ }
313
+ ]
314
+
315
+ test_cases.each do |test_case|
316
+ it "#{test_case[:title]}" do
317
+ generated_config = NatService.new(@edge_id, test_case[:input]).generate_fog_config
318
+ expect(generated_config).to eq(test_case[:output])
319
+ end
320
+ end
321
+
322
+ it "should only make a single API call per network specified" do
323
+ input = {
324
+ nat_rules: [
325
+ {
326
+ rule_type: 'DNAT',
327
+ network_id: '2ad93597-7b54-43dd-9eb1-631dd337e5a7',
328
+ original_ip: "192.0.2.2",
329
+ original_port: '8081',
330
+ translated_port: '8081',
331
+ translated_ip: "10.10.20.21",
332
+ },
333
+ {
334
+ rule_type: 'DNAT',
335
+ network_id: '2ad93597-7b54-43dd-9eb1-631dd337e5a7',
336
+ original_ip: "192.0.2.2",
337
+ original_port: '8082',
338
+ translated_port: '8082',
339
+ translated_ip: "10.10.20.22",
340
+ },
341
+ {
342
+ rule_type: 'DNAT',
343
+ network_id: '2ad93597-7b54-43dd-9eb1-631dd337e5a7',
344
+ original_ip: "192.0.2.2",
345
+ original_port: '8083',
346
+ translated_port: '8083',
347
+ translated_ip: "10.10.20.23",
348
+ },
349
+ ]
350
+ }
351
+ expect(@mock_edge_gateway).
352
+ to receive(:vcloud_gateway_interface_by_id).exactly(1).times
353
+ NatService.new(@edge_id, input).generate_fog_config
354
+ end
355
+
356
+ end
357
+ end
358
+ end
359
+ end
360
+ end
@@ -0,0 +1,182 @@
1
+ require 'spec_helper'
2
+
3
+ module Vcloud
4
+ module EdgeGateway
5
+ describe EdgeGatewayConfiguration do
6
+
7
+ context "whether update is required" do
8
+
9
+ before(:each) do
10
+ @edge_gateway_id = "1111111-7b54-43dd-9eb1-631dd337e5a7"
11
+ @edge_gateway = double(:edge_gateway,
12
+ :vcloud_gateway_interface_by_id => {
13
+ Network: {
14
+ :name => 'ane012345',
15
+ :href => 'https://vmware.example.com/api/admin/network/01234567-1234-1234-1234-0123456789aa'
16
+ }
17
+ })
18
+ Vcloud::Core::EdgeGateway.stub(:get_by_name).with(@edge_gateway_id).and_return(@edge_gateway)
19
+ end
20
+
21
+ it "requires update to both when both configurations are changed" do
22
+ test_config = {
23
+ :gateway=> @edge_gateway_id,
24
+ :nat_service=> test_nat_config,
25
+ :firewall_service=> test_firewall_config
26
+ }
27
+
28
+ proposed_config = EdgeGateway::EdgeGatewayConfiguration.new(test_config)
29
+
30
+ remote_config = {
31
+ :FirewallService=> different_firewall_config,
32
+ :NatService=> different_nat_config
33
+ }
34
+
35
+ expect(proposed_config.update_required?(remote_config)).to be_true
36
+
37
+ proposed_firewall_config = proposed_config.config[:FirewallService]
38
+ expect(proposed_firewall_config).to eq(expected_firewall_config)
39
+
40
+ proposed_nat_config = proposed_config.config[:NatService]
41
+ expect(proposed_nat_config).to eq(expected_nat_config)
42
+ end
43
+
44
+ it "requires update to firewall only when firewall has changed and nat has not" do
45
+ test_config = {
46
+ :gateway=> @edge_gateway_id,
47
+ :nat_service=> test_nat_config,
48
+ :firewall_service=> test_firewall_config
49
+ }
50
+
51
+ proposed_config = EdgeGateway::EdgeGatewayConfiguration.new(test_config)
52
+
53
+ remote_config = {
54
+ :FirewallService=> different_firewall_config,
55
+ :NatService=> same_nat_config
56
+ }
57
+
58
+ expect(proposed_config.update_required?(remote_config)).to be_true
59
+
60
+ proposed_firewall_config = proposed_config.config[:FirewallService]
61
+ expect(proposed_firewall_config).to eq(expected_firewall_config)
62
+
63
+ expect(proposed_config.config.key?(:NatService)).to be_false
64
+ end
65
+
66
+ it "requires update to firewall only when firewall has changed and nat is absent" do
67
+ test_config = {
68
+ :gateway=> @edge_gateway_id,
69
+ :firewall_service=> test_firewall_config
70
+ }
71
+
72
+ proposed_config = EdgeGateway::EdgeGatewayConfiguration.new(test_config)
73
+
74
+ remote_config = {
75
+ :FirewallService=> different_firewall_config,
76
+ :NatService=> same_nat_config
77
+ }
78
+
79
+ expect(proposed_config.update_required?(remote_config)).to be_true
80
+
81
+ proposed_firewall_config = proposed_config.config[:FirewallService]
82
+ expect(proposed_firewall_config).to eq(expected_firewall_config)
83
+
84
+ #expect proposed config not to contain nat config
85
+ expect(proposed_config.config.key?(:NatService)).to be_false
86
+ end
87
+
88
+ it "does not require change when both configs are present but have not changed" do
89
+ test_config = {
90
+ :gateway=> @edge_gateway_id,
91
+ :nat_service=> test_nat_config,
92
+ :firewall_service=> test_firewall_config
93
+ }
94
+
95
+ proposed_config = EdgeGateway::EdgeGatewayConfiguration.new(test_config)
96
+
97
+ remote_config = {
98
+ :FirewallService=> same_firewall_config,
99
+ :NatService=> same_nat_config
100
+ }
101
+
102
+ expect(proposed_config.update_required?(remote_config)).to be_false
103
+ expect(proposed_config.config.empty?).to be_true
104
+ end
105
+
106
+ it "does not require change when firewall is unchanged and nat is absent" do
107
+ test_config = {
108
+ :gateway=> @edge_gateway_id,
109
+ :firewall_service=> test_firewall_config
110
+ }
111
+
112
+ proposed_config = EdgeGateway::EdgeGatewayConfiguration.new(test_config)
113
+
114
+ remote_config = {
115
+ :FirewallService=> same_firewall_config,
116
+ :NatService=> different_nat_config
117
+ }
118
+
119
+ expect(proposed_config.update_required?(remote_config)).to be_false
120
+ expect(proposed_config.config.empty?).to be_true
121
+ end
122
+
123
+ it "does not require change when both are absent" do
124
+ test_config = {
125
+ :gateway=> @edge_gateway_id,
126
+ }
127
+
128
+ proposed_config = EdgeGateway::EdgeGatewayConfiguration.new(test_config)
129
+
130
+ remote_config = {
131
+ :FirewallService=> different_firewall_config,
132
+ :NatService=> different_nat_config
133
+ }
134
+
135
+ expect(proposed_config.update_required?(remote_config)).to be_false
136
+ expect(proposed_config.config.empty?).to be_true
137
+ end
138
+
139
+ it "does not require change if local configuration is in unexpected format" do
140
+
141
+ end
142
+
143
+ it "does not require change if remote configuration is in unexpected format" do
144
+
145
+ end
146
+
147
+ end
148
+
149
+ def test_firewall_config
150
+ {:policy=>"drop", :log_default_action=>true, :firewall_rules=>[{:enabled=>true, :description=>"A rule", :policy=>"allow", :protocols=>"tcp", :destination_port_range=>"Any", :destination_ip=>"10.10.1.2", :source_port_range=>"Any", :source_ip=>"192.0.2.2"}, {:enabled=>true, :destination_ip=>"10.10.1.3-10.10.1.5", :source_ip=>"192.0.2.2/24"}]}
151
+ end
152
+
153
+ def test_nat_config
154
+ {:nat_rules=>[{:enabled=>true, :network_id=>"01234567-1234-1234-1234-0123456789ab", :rule_type=>"DNAT", :translated_ip=>"10.10.1.2-10.10.1.3", :translated_port=>"3412", :original_ip=>"192.0.2.58", :original_port=>"3412", :protocol=>"tcp"}]}
155
+ end
156
+
157
+ def different_firewall_config
158
+ {:IsEnabled=>"true", :DefaultAction=>"drop", :LogDefaultAction=>"false", :FirewallRule=>[{:Id=>"1", :IsEnabled=>"true", :MatchOnTranslate=>"false", :Description=>"A rule", :Policy=>"allow", :Protocols=>{:Tcp=>"true"}, :Port=>"-1", :DestinationPortRange=>"Any", :DestinationIp=>"10.10.1.2", :SourcePort=>"-1", :SourcePortRange=>"Any", :SourceIp=>"192.0.2.2", :EnableLogging=>"false"}]}
159
+ end
160
+
161
+ def different_nat_config
162
+ {:IsEnabled=>"true", :NatRule=>[{:RuleType=>"SNAT", :IsEnabled=>"true", :Id=>"65538", :GatewayNatRule=>{:Interface=>{:type=>"application/vnd.vmware.admin.network+xml", :name=>"RemoteVSE", :href=>"https://api.vmware.example.com/api/admin/network/01234567-1234-1234-1234-012345678912"}, :OriginalIp=>"10.10.1.2-10.10.1.3", :TranslatedIp=>"192.0.2.40"}}]}
163
+ end
164
+
165
+ def same_firewall_config
166
+ {:IsEnabled=>"true", :DefaultAction=>"drop", :LogDefaultAction=>"true", :FirewallRule=>[{:Id=>"1", :IsEnabled=>"true", :MatchOnTranslate=>"false", :Description=>"A rule", :Policy=>"allow", :Protocols=>{:Tcp=>"true"}, :DestinationPortRange=>"Any", :Port=>"-1", :DestinationIp=>"10.10.1.2", :SourcePortRange=>"Any", :SourcePort=>"-1", :SourceIp=>"192.0.2.2", :EnableLogging=>"false"}, {:Id=>"2", :IsEnabled=>"true", :MatchOnTranslate=>"false", :Description=>"", :Policy=>"allow", :Protocols=>{:Tcp=>"true"}, :DestinationPortRange=>"Any", :Port=>"-1", :DestinationIp=>"10.10.1.3-10.10.1.5", :SourcePortRange=>"Any", :SourcePort=>"-1", :SourceIp=>"192.0.2.2/24", :EnableLogging=>"false"}]}
167
+ end
168
+
169
+ def same_nat_config
170
+ {:IsEnabled=>"true", :NatRule=>[{:Id=>"65537", :IsEnabled=>"true", :RuleType=>"DNAT", :GatewayNatRule=>{:Interface=>{:name=>"ane012345", :href=>"https://vmware.example.com/api/admin/network/01234567-1234-1234-1234-0123456789aa"}, :OriginalIp=>"192.0.2.58", :TranslatedIp=>"10.10.1.2-10.10.1.3", :OriginalPort=>"3412", :TranslatedPort=>"3412", :Protocol=>"tcp"}}]}
171
+ end
172
+
173
+ def expected_firewall_config
174
+ {:IsEnabled=>"true", :DefaultAction=>"drop", :LogDefaultAction=>"true", :FirewallRule=>[{:Id=>"1", :IsEnabled=>"true", :MatchOnTranslate=>"false", :Description=>"A rule", :Policy=>"allow", :Protocols=>{:Tcp=>"true"}, :DestinationPortRange=>"Any", :Port=>"-1", :DestinationIp=>"10.10.1.2", :SourcePortRange=>"Any", :SourcePort=>"-1", :SourceIp=>"192.0.2.2", :EnableLogging=>"false"}, {:Id=>"2", :IsEnabled=>"true", :MatchOnTranslate=>"false", :Description=>"", :Policy=>"allow", :Protocols=>{:Tcp=>"true"}, :DestinationPortRange=>"Any", :Port=>"-1", :DestinationIp=>"10.10.1.3-10.10.1.5", :SourcePortRange=>"Any", :SourcePort=>"-1", :SourceIp=>"192.0.2.2/24", :EnableLogging=>"false"}]}
175
+ end
176
+
177
+ def expected_nat_config
178
+ {:IsEnabled=>"true", :NatRule=>[{:Id=>"65537", :IsEnabled=>"true", :RuleType=>"DNAT", :GatewayNatRule=>{:Interface=>{:name=>"ane012345", :href=>"https://vmware.example.com/api/admin/network/01234567-1234-1234-1234-0123456789aa"}, :OriginalIp=>"192.0.2.58", :TranslatedIp=>"10.10.1.2-10.10.1.3", :OriginalPort=>"3412", :TranslatedPort=>"3412", :Protocol=>"tcp"}}]}
179
+ end
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ module Vcloud
4
+ describe 'firewall_service_schema_validations' do
5
+ context 'source and destination ips' do
6
+ it 'should error if source_ip/destination_ip are invalid IPs' do
7
+ config = {
8
+ firewall_rules: [
9
+ {
10
+ id: '999',
11
+ description: "A rule",
12
+ destination_port_range: "22",
13
+ destination_ip: "10.10",
14
+ source_ip: "192.0",
15
+ }
16
+ ]
17
+
18
+ }
19
+ validator = ConfigValidator.validate(:base, config, Schema::FIREWALL_SERVICE)
20
+ expect(validator.valid?).to be_false
21
+ expect(validator.errors).to eq([
22
+ "source_ip: 192.0 is not a valid IP address range. Valid values can be IP address, CIDR, IP range, 'Any','internal' and 'external'.",
23
+ "destination_ip: 10.10 is not a valid IP address range. Valid values can be IP address, CIDR, IP range, 'Any','internal' and 'external'."
24
+ ])
25
+ end
26
+
27
+ it 'should validate OK if source_ip/destination_ip are valid IPs' do
28
+ config = {
29
+ firewall_rules: [
30
+ {
31
+ id: '999',
32
+ description: "A rule",
33
+ destination_port_range: "22",
34
+ destination_ip: "10.10.10.20",
35
+ source_ip: "192.0.2.2",
36
+ }
37
+ ]
38
+
39
+ }
40
+ validator = ConfigValidator.validate(:base, config, Schema::FIREWALL_SERVICE)
41
+ expect(validator.valid?).to be_true
42
+ end
43
+ end
44
+ end
45
+ end