vcloud-edge_gateway 0.0.1

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.
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