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,243 @@
1
+ module Vcloud
2
+ module EdgeGateway
3
+ module ConfigurationGenerator
4
+ class LoadBalancerService
5
+
6
+ def initialize edge_gateway
7
+ @edge_gateway = Vcloud::Core::EdgeGateway.get_by_name(edge_gateway)
8
+ end
9
+
10
+ def generate_fog_config(load_balancer_input_config)
11
+ return nil if load_balancer_input_config.nil?
12
+ vcloud_load_balancer_section = {}
13
+ vcloud_load_balancer_section[:IsEnabled] =
14
+ load_balancer_input_config.key?(:enabled) ?
15
+ load_balancer_input_config[:enabled].to_s : 'true'
16
+ vcloud_pools = []
17
+ vcloud_virtual_servers = []
18
+ if pools = load_balancer_input_config[:pools]
19
+ pools.each do |pool_input_entry|
20
+ vcloud_pools << generate_pool_entry(pool_input_entry)
21
+ end
22
+ end
23
+ if virtual_servers = load_balancer_input_config[:virtual_servers]
24
+ virtual_servers.each do |virtual_server_input_entry|
25
+ vcloud_virtual_servers << generate_virtual_server_entry(virtual_server_input_entry)
26
+ end
27
+ end
28
+ vcloud_load_balancer_section[:Pool] = vcloud_pools
29
+ vcloud_load_balancer_section[:VirtualServer] = vcloud_virtual_servers
30
+ vcloud_load_balancer_section
31
+ end
32
+
33
+ private
34
+
35
+ def generate_virtual_server_entry(input_virtual_server)
36
+ vcloud_virtual_server = {}
37
+ vcloud_virtual_server[:IsEnabled] =
38
+ input_virtual_server.key(:enabled) ? input_virtual_server[:enabled] : 'true'
39
+ vcloud_virtual_server[:Name] = input_virtual_server[:name]
40
+ vcloud_virtual_server[:Description] =
41
+ input_virtual_server[:description] || ''
42
+ vcloud_virtual_server[:Interface] =
43
+ generate_virtual_server_interface_section(input_virtual_server[:network])
44
+ vcloud_virtual_server[:IpAddress] = input_virtual_server[:ip_address]
45
+ vcloud_virtual_server[:ServiceProfile] =
46
+ generate_virtual_server_service_profile_section(input_virtual_server[:service_profiles])
47
+ vcloud_virtual_server[:Logging] =
48
+ input_virtual_server.key(:logging) ? input_virtual_server[:logging] : 'false'
49
+ vcloud_virtual_server[:Pool] = input_virtual_server[:pool]
50
+ vcloud_virtual_server
51
+ end
52
+
53
+ def generate_virtual_server_interface_section(network_id)
54
+ vcloud_virtual_server_interface = {}
55
+ vcloud_virtual_server_interface[:type] = 'application/vnd.vmware.vcloud.orgVdcNetwork+xml'
56
+ vcloud_virtual_server_interface[:name] = look_up_network_name(network_id)
57
+ vcloud_virtual_server_interface[:href] = look_up_network_href(network_id)
58
+ vcloud_virtual_server_interface
59
+ end
60
+
61
+ def look_up_network_name(network_id)
62
+ gateway_interface = @edge_gateway.vcloud_gateway_interface_by_id(network_id)
63
+ raise "Could not find network #{network_id}" unless gateway_interface
64
+ gateway_interface[:Network][:name]
65
+ end
66
+
67
+ def look_up_network_href(network_id)
68
+ gateway_interface = @edge_gateway.vcloud_gateway_interface_by_id(network_id)
69
+ raise "Could not find network #{network_id}" unless gateway_interface
70
+ gateway_interface[:Network][:href]
71
+ end
72
+
73
+ def generate_virtual_server_service_profile_section(input_service_profile)
74
+ input_service_profile = {} if input_service_profile.nil?
75
+ vcloud_service_profiles = []
76
+ protocols = [ :http, :https, :tcp ]
77
+ protocols.each do |protocol|
78
+ vcloud_service_profiles <<
79
+ generate_virtual_server_service_profile_protocol_section(
80
+ protocol,
81
+ input_service_profile[protocol]
82
+ )
83
+ end
84
+ vcloud_service_profiles
85
+ end
86
+
87
+ def generate_virtual_server_service_profile_protocol_section(protocol, input_protocol_section)
88
+ vcloud_protocol_section = {
89
+ IsEnabled: 'false',
90
+ Protocol: protocol.to_s.upcase,
91
+ Port: default_port(protocol),
92
+ Persistence: generate_virtual_server_persistence_section(protocol, nil)
93
+ }
94
+ if input_protocol_section
95
+ vcloud_protocol_section[:IsEnabled] =
96
+ input_protocol_section.key?(:enabled) ?
97
+ input_protocol_section[:enabled].to_s : 'true'
98
+ vcloud_protocol_section[:Port] =
99
+ input_protocol_section.key?(:port) ?
100
+ input_protocol_section[:port].to_s : default_port(protocol)
101
+ vcloud_protocol_section[:Persistence] =
102
+ generate_virtual_server_persistence_section(
103
+ protocol,
104
+ input_protocol_section[:persistence]
105
+ )
106
+ end
107
+ vcloud_protocol_section
108
+ end
109
+
110
+ def default_port(protocol)
111
+ default_port_for = { http: '80', https: '443', tcp: '' }
112
+ default_port_for[protocol]
113
+ end
114
+
115
+ def generate_virtual_server_persistence_section(protocol, input_persistence_section)
116
+ input_persistence_section = {} if input_persistence_section.nil?
117
+ vcloud_persistence_section = { Method: '' }
118
+ if input_persistence_section.key?(:method)
119
+ if input_persistence_section.key?(:method)
120
+ vcloud_persistence_section[:Method] = input_persistence_section[:method]
121
+ end
122
+ if input_persistence_section[:method] == 'COOKIE'
123
+ vcloud_persistence_section[:CookieName] = input_persistence_section[:cookie_name]
124
+ vcloud_persistence_section[:CookieMode] = input_persistence_section[:cookie_mode]
125
+ end
126
+ end
127
+ vcloud_persistence_section
128
+ end
129
+
130
+ def generate_pool_entry(input_pool_entry)
131
+ service_port_modes = [ :http, :https, :tcp ]
132
+ vcloud_pool_entry = {}
133
+ vcloud_pool_entry[:Name] = input_pool_entry[:name]
134
+ if input_pool_entry.key?(:description)
135
+ vcloud_pool_entry[:Description] = input_pool_entry[:description]
136
+ end
137
+ vcloud_pool_entry[:ServicePort] = service_port_modes.map do |mode|
138
+ generate_pool_service_port(
139
+ mode,
140
+ input_pool_entry.key?(:service) ? input_pool_entry[:service][mode] : nil
141
+ )
142
+ end
143
+ if input_pool_entry.key?(:members)
144
+ vcloud_pool_entry[:Member] = []
145
+ input_pool_entry[:members].each do |member|
146
+ vcloud_pool_entry[:Member] << generate_pool_member_entry(member)
147
+ end
148
+ end
149
+ vcloud_pool_entry
150
+ end
151
+
152
+ def generate_pool_member_entry(input_pool_member)
153
+ {
154
+ IpAddress: input_pool_member[:ip_address],
155
+ Weight: input_pool_member.key?(:weight) ? input_pool_member[:weight].to_s : '1',
156
+ ServicePort: [
157
+ { Protocol: 'HTTP', Port: '', HealthCheckPort: '' },
158
+ { Protocol: 'HTTPS', Port: '', HealthCheckPort: '' },
159
+ { Protocol: 'TCP', Port: '', HealthCheckPort: '' },
160
+ ]
161
+ }
162
+ end
163
+
164
+ def generate_pool_service_port(mode, input_pool_service_port)
165
+
166
+ vcloud_pool_service_port = {
167
+ IsEnabled: 'false',
168
+ Protocol: mode.to_s.upcase,
169
+ Algorithm: 'ROUND_ROBIN',
170
+ Port: default_port(mode),
171
+ HealthCheckPort: '',
172
+ HealthCheck: generate_pool_healthcheck(mode)
173
+ }
174
+
175
+ if input_pool_service_port
176
+ vcloud_pool_service_port[:IsEnabled] =
177
+ input_pool_service_port.key?(:enabled) ?
178
+ input_pool_service_port[:enabled].to_s : 'true'
179
+ if input_pool_service_port.key?(:algorithm)
180
+ vcloud_pool_service_port[:Algorithm] = input_pool_service_port[:algorithm]
181
+ end
182
+ vcloud_pool_service_port[:Port] =
183
+ input_pool_service_port.key?(:port) ?
184
+ input_pool_service_port[:port].to_s : default_port(mode)
185
+ if health_check = input_pool_service_port[:health_check]
186
+ vcloud_pool_service_port[:HealthCheckPort] =
187
+ health_check.key?(:port) ? health_check[:port].to_s : ''
188
+ vcloud_pool_service_port[:HealthCheck] =
189
+ generate_pool_healthcheck(mode, input_pool_service_port[:health_check])
190
+ end
191
+ end
192
+ vcloud_pool_service_port
193
+ end
194
+
195
+ def generate_pool_healthcheck(protocol, input_pool_healthcheck_entry = nil)
196
+ default_mode = ( protocol == :https ) ? 'SSL' : protocol.to_s.upcase
197
+ vcloud_pool_healthcheck_entry = {
198
+ Mode: default_mode,
199
+ }
200
+ if protocol == :http
201
+ vcloud_pool_healthcheck_entry[:Uri] = ''
202
+ elsif ( protocol == :https ) &&
203
+ input_pool_healthcheck_entry &&
204
+ ( input_pool_healthcheck_entry[:protocol] == 'TCP' )
205
+ vcloud_pool_healthcheck_entry[:Uri] = ''
206
+ end
207
+ vcloud_pool_healthcheck_entry[:HealthThreshold] = '2'
208
+ vcloud_pool_healthcheck_entry[:UnhealthThreshold] = '3'
209
+ vcloud_pool_healthcheck_entry[:Interval] = '5'
210
+ vcloud_pool_healthcheck_entry[:Timeout] = '15'
211
+
212
+ if input_pool_healthcheck_entry
213
+ if input_pool_healthcheck_entry.key?(:protocol)
214
+ vcloud_pool_healthcheck_entry[:Mode] = input_pool_healthcheck_entry[:protocol]
215
+ end
216
+ if input_pool_healthcheck_entry.key?(:uri) and protocol == :http
217
+ vcloud_pool_healthcheck_entry[:Uri] = input_pool_healthcheck_entry[:uri]
218
+ end
219
+ if input_pool_healthcheck_entry.key?(:health_threshold)
220
+ vcloud_pool_healthcheck_entry[:HealthThreshold] =
221
+ input_pool_healthcheck_entry[:health_threshold]
222
+ end
223
+ if input_pool_healthcheck_entry.key?(:unhealth_threshold)
224
+ vcloud_pool_healthcheck_entry[:UnhealthThreshold] =
225
+ input_pool_healthcheck_entry[:unhealth_threshold]
226
+ end
227
+ if input_pool_healthcheck_entry.key?(:interval)
228
+ vcloud_pool_healthcheck_entry[:Interval] =
229
+ input_pool_healthcheck_entry[:interval]
230
+ end
231
+ if input_pool_healthcheck_entry.key?(:timeout)
232
+ vcloud_pool_healthcheck_entry[:Timeout] =
233
+ input_pool_healthcheck_entry[:timeout]
234
+ end
235
+ end
236
+ vcloud_pool_healthcheck_entry
237
+ end
238
+
239
+ end
240
+ end
241
+ end
242
+
243
+ end
@@ -0,0 +1,54 @@
1
+ module Vcloud
2
+ module EdgeGateway
3
+ module ConfigurationGenerator
4
+
5
+ class NatService
6
+ def initialize edge_gateway, input_config
7
+ @edge_gateway = Vcloud::Core::EdgeGateway.get_by_name(edge_gateway)
8
+ @input_config = input_config
9
+ @interfaces_by_id = {}
10
+ end
11
+
12
+ def generate_fog_config
13
+ if @input_config
14
+ nat_service = {}
15
+ nat_service[:IsEnabled] = @input_config.key?(:enabled) ? @input_config[:enabled].to_s : 'true'
16
+ nat_service[:NatRule] = populate_nat_rules
17
+ nat_service
18
+ end
19
+ end
20
+
21
+ def populate_nat_rules
22
+ rules = @input_config[:nat_rules]
23
+ i = ID_RANGES::NAT_SERVICE[:min]
24
+ rules.collect do |rule|
25
+ new_rule = {}
26
+ new_rule[:Id] = rule.key?(:id) ? rule[:id] : i.to_s
27
+ new_rule[:IsEnabled] = rule.key?(:enabled) ? rule[:enabled].to_s : 'true'
28
+ new_rule[:RuleType] = rule[:rule_type]
29
+ gateway_nat_rule = populate_gateway_nat_rule(rule)
30
+ new_rule[:GatewayNatRule] = gateway_nat_rule
31
+ i += 1
32
+ new_rule
33
+ end
34
+ end
35
+
36
+ def populate_gateway_nat_rule(rule)
37
+ raise "Must supply a :network_id parameter" unless net_id = rule[:network_id]
38
+ @interfaces_by_id[net_id] ||= @edge_gateway.vcloud_gateway_interface_by_id(net_id)
39
+ raise "unable to find gateway network interface with id #{net_id}" unless @interfaces_by_id[net_id]
40
+ gateway_nat_rule = {:Interface => @interfaces_by_id[net_id][:Network]}
41
+ gateway_nat_rule[:OriginalIp] = rule[:original_ip]
42
+ gateway_nat_rule[:TranslatedIp] = rule[:translated_ip]
43
+ gateway_nat_rule[:OriginalPort] = rule[:original_port] if rule.key?(:original_port)
44
+ gateway_nat_rule[:TranslatedPort] = rule[:translated_port] if rule.key?(:translated_port)
45
+ if rule[:rule_type] == 'DNAT'
46
+ gateway_nat_rule[:Protocol] = rule.key?(:protocol) ? rule[:protocol] : "tcp"
47
+ end
48
+ gateway_nat_rule
49
+ end
50
+
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,41 @@
1
+ module Vcloud
2
+ module EdgeGateway
3
+ class EdgeGatewayConfiguration
4
+
5
+ def initialize(local_config)
6
+ @local_config = local_config
7
+ @config = { }
8
+ end
9
+
10
+ def update_required?(remote_config)
11
+ update_required = false
12
+
13
+ firewall_service_config = EdgeGateway::ConfigurationGenerator::FirewallService.new.generate_fog_config(@local_config[:firewall_service])
14
+ unless firewall_service_config.nil?
15
+ differ = EdgeGateway::ConfigurationDiffer.new(firewall_service_config, remote_config[:FirewallService])
16
+ unless differ.diff.empty?
17
+ @config[:FirewallService] = firewall_service_config
18
+ update_required = true
19
+ end
20
+ end
21
+
22
+ nat_service_config = EdgeGateway::ConfigurationGenerator::NatService.new(@local_config[:gateway], @local_config[:nat_service]).generate_fog_config
23
+
24
+ unless nat_service_config.nil?
25
+ differ = EdgeGateway::ConfigurationDiffer.new(nat_service_config, remote_config[:NatService])
26
+ unless differ.diff.empty?
27
+ @config[:NatService] = nat_service_config
28
+ update_required = true
29
+ end
30
+ end
31
+
32
+ update_required
33
+ end
34
+
35
+ def config
36
+ @config
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,6 @@
1
+ module Vcloud
2
+ module EdgeGateway
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
6
+
@@ -0,0 +1,32 @@
1
+ require 'vcloud/edge_gateway/version'
2
+
3
+ require 'vcloud/core'
4
+ require 'vcloud/fog'
5
+
6
+ require 'vcloud/config_loader'
7
+ require 'vcloud/config_validator'
8
+
9
+ require 'vcloud/edge_gateway_services'
10
+
11
+ require 'vcloud/schema/nat_service'
12
+ require 'vcloud/schema/firewall_service'
13
+ require 'vcloud/schema/load_balancer_service'
14
+ require 'vcloud/schema/edge_gateway'
15
+
16
+ require 'vcloud/edge_gateway/configuration_generator/id_ranges'
17
+ require 'vcloud/edge_gateway/configuration_generator/firewall_service'
18
+ require 'vcloud/edge_gateway/configuration_generator/nat_service'
19
+ require 'vcloud/edge_gateway/configuration_generator/load_balancer_service'
20
+ require 'vcloud/edge_gateway/configuration_differ'
21
+ require 'vcloud/edge_gateway/edge_gateway_configuration'
22
+
23
+
24
+ module Vcloud
25
+ module EdgeGateway
26
+
27
+ def self.logger
28
+ @logger ||=Logger.new(STDOUT)
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,26 @@
1
+ require 'hashdiff'
2
+
3
+ module Vcloud
4
+ class EdgeGatewayServices
5
+
6
+ def initialize
7
+ @config_loader = Vcloud::ConfigLoader.new
8
+ end
9
+
10
+ def update(config_file = nil)
11
+ config = @config_loader.load_config(config_file, Vcloud::Schema::EDGE_GATEWAY_SERVICES)
12
+
13
+ edge_gateway = Core::EdgeGateway.get_by_name config[:gateway]
14
+ remote_config = edge_gateway.vcloud_attributes[:Configuration][:EdgeGatewayServiceConfiguration]
15
+
16
+ proposed_config = EdgeGateway::EdgeGatewayConfiguration.new(config)
17
+
18
+ if proposed_config.update_required?(remote_config)
19
+ edge_gateway.update_configuration proposed_config.config
20
+ else
21
+ Vcloud::EdgeGateway.logger.info("EdgeGatewayServices.update: Configuration is already up to date. Skipping.")
22
+ end
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ module Vcloud
2
+ module Schema
3
+
4
+ EDGE_GATEWAY_SERVICES = {
5
+ type: 'hash',
6
+ allowed_empty: false,
7
+ internals: {
8
+ gateway: { type: 'string' },
9
+ firewall_service: FIREWALL_SERVICE,
10
+ nat_service: NAT_SERVICE
11
+ }
12
+ }
13
+
14
+ end
15
+ end
@@ -0,0 +1,39 @@
1
+ module Vcloud
2
+ module Schema
3
+
4
+ FIREWALL_RULE = {
5
+ type: Hash,
6
+ internals: {
7
+ id: { type: 'string_or_number', required: false},
8
+ enabled: { type: 'boolean', required: false},
9
+ match_on_translate: { type: 'boolean', required: false},
10
+ description: { type: 'string', required: false, allowed_empty: true},
11
+ policy: { type: 'enum', required: false, acceptable_values: ['allow', 'drop'] },
12
+ source_ip: { type: 'ip_address_range', required: true },
13
+ destination_ip: { type: 'ip_address_range', required: true },
14
+ source_port_range: { type: 'string', required: false },
15
+ destination_port_range: { type: 'string', required: false },
16
+ enable_logging: { type: 'boolean', required: false },
17
+ protocols: { type: 'enum', required: false, acceptable_values: ['tcp', 'udp', 'icmp', 'tcp+udp', 'any']},
18
+ }
19
+ }
20
+
21
+ FIREWALL_SERVICE = {
22
+ type: Hash,
23
+ allowed_empty: true,
24
+ required: false,
25
+ internals: {
26
+ enabled: { type: 'boolean', required: false},
27
+ policy: { type: 'enum', required: false, acceptable_values: ['allow', 'drop'] },
28
+ log_default_action: { type: 'boolean', required: false},
29
+ firewall_rules: {
30
+ type: Array,
31
+ required: false,
32
+ allowed_empty: true,
33
+ each_element_is: FIREWALL_RULE
34
+ }
35
+ }
36
+ }
37
+
38
+ end
39
+ end
@@ -0,0 +1,129 @@
1
+ module Vcloud
2
+ module Schema
3
+
4
+ POOL_MEMBER_SERVICE_PORT_ENTRY = {
5
+ type: Hash,
6
+ required: false,
7
+ internals: {
8
+ port: { type: 'string_or_number', required: false },
9
+ health_check_port: { type: 'string_or_number', required: false },
10
+ }
11
+ }
12
+
13
+ LOAD_BALANCER_MEMBER_ENTRY = {
14
+ type: Hash,
15
+ internals: {
16
+ ip_address: { type: 'ip_address', required: true },
17
+ weight: { type: 'string_or_number', required: false },
18
+ service_port: {
19
+ type: 'hash',
20
+ required: false,
21
+ internals: {
22
+ http: POOL_MEMBER_SERVICE_PORT_ENTRY,
23
+ https: POOL_MEMBER_SERVICE_PORT_ENTRY,
24
+ tcp: POOL_MEMBER_SERVICE_PORT_ENTRY,
25
+ },
26
+ },
27
+ },
28
+ }
29
+
30
+ POOL_SERVICE_SECTION = {
31
+ type: Hash,
32
+ required: false,
33
+ internals: {
34
+ enabled: { type: 'boolean', required: false },
35
+ port: { type: 'string_or_number', required: false },
36
+ algorithm: { type: 'enum', required: false,
37
+ acceptable_values: [ 'ROUND_ROBIN', 'IP_HASH', 'URI', 'LEAST_CONNECTED' ]},
38
+ health_check: {
39
+ type: 'hash',
40
+ required: false,
41
+ internals: {
42
+ port: { type: 'string_or_number', required: false },
43
+ uri: { type: 'string', required: false },
44
+ protocol: { type: 'enum', required: false,
45
+ acceptable_values: [ 'HTTP', 'SSL', 'TCP' ] },
46
+ health_threshold: { type: 'string_or_number', required: false },
47
+ unhealth_threshold: { type: 'string_or_number', required: false },
48
+ interval: { type: 'string_or_number', required: false },
49
+ timeout: { type: 'string_or_number', required: false },
50
+ },
51
+ },
52
+ }
53
+ }
54
+
55
+ LOAD_BALANCER_POOL_ENTRY = {
56
+ type: Hash,
57
+ internals: {
58
+ name: { type: 'string', required: true },
59
+ description: { type: 'string', required: false },
60
+ service: {
61
+ type: 'hash',
62
+ required: false,
63
+ internals: {
64
+ http: POOL_SERVICE_SECTION,
65
+ https: POOL_SERVICE_SECTION,
66
+ tcp: POOL_SERVICE_SECTION,
67
+ }
68
+ },
69
+ members: {
70
+ type: Array,
71
+ required: true,
72
+ allowed_empty: false,
73
+ each_element_is: LOAD_BALANCER_MEMBER_ENTRY,
74
+ }
75
+ }
76
+ }
77
+
78
+ VIRTUAL_SERVER_SERVICE_PROFILE_ENTRY = {
79
+ type: Hash,
80
+ required: false,
81
+ internals: {
82
+ enabled: { type: 'boolean', required: false },
83
+ port: { type: 'string_or_number', required: false },
84
+ }
85
+ }
86
+
87
+ LOAD_BALANCER_VIRTUAL_SERVER_ENTRY = {
88
+ type: Hash,
89
+ internals: {
90
+ enabled: { type: 'boolean', required: false },
91
+ name: { type: 'string', required: true },
92
+ description: { type: 'string', required: false },
93
+ ip_address: { type: 'ip_address', required: true },
94
+ network: { type: 'string', required: true },
95
+ pool: { type: 'string', required: true },
96
+ logging: { type: 'boolean', required: false },
97
+ service_profiles: {
98
+ type: 'hash',
99
+ required: false,
100
+ internals: {
101
+ http: VIRTUAL_SERVER_SERVICE_PROFILE_ENTRY,
102
+ https: VIRTUAL_SERVER_SERVICE_PROFILE_ENTRY,
103
+ tcp: VIRTUAL_SERVER_SERVICE_PROFILE_ENTRY,
104
+ },
105
+ },
106
+ }
107
+ }
108
+
109
+ LOAD_BALANCER_SERVICE = {
110
+ type: Hash,
111
+ allowed_empty: true,
112
+ internals: {
113
+ enabled: { type: 'boolean', required: false },
114
+ pools: {
115
+ type: Array,
116
+ required: true,
117
+ allowed_empty: true,
118
+ each_element_is: LOAD_BALANCER_POOL_ENTRY,
119
+ },
120
+ virtual_servers: {
121
+ type: Array,
122
+ required: true,
123
+ allowed_empty: true,
124
+ each_element_is: LOAD_BALANCER_VIRTUAL_SERVER_ENTRY,
125
+ },
126
+ }
127
+ }
128
+ end
129
+ end
@@ -0,0 +1,35 @@
1
+ module Vcloud
2
+ module Schema
3
+
4
+ NAT_RULE = {
5
+ type: Hash,
6
+ internals: {
7
+ id: {type: 'string_or_number', required: false},
8
+ enabled: {type: 'boolean', required: false},
9
+ rule_type: { type: 'enum', required: true, acceptable_values: ['SNAT', 'DNAT' ]},
10
+ description: {type: 'string', required: false, allowed_empty: true},
11
+ network_id: {type: 'string', required: true},
12
+ original_ip: {type: 'ip_address_range', required: true},
13
+ original_port: {type: 'string', required: false},
14
+ translated_ip: {type: 'ip_address_range', required: true},
15
+ translated_port: {type: 'string', required: false},
16
+ protocol: {type: 'enum', required: false, acceptable_values: ['tcp', 'udp', 'icmp', 'tcp+udp', 'any']},
17
+ }
18
+ }
19
+
20
+ NAT_SERVICE = {
21
+ type: Hash,
22
+ allowed_empty: true,
23
+ required: false,
24
+ internals: {
25
+ enabled: {type: 'boolean', required: false},
26
+ nat_rules: {
27
+ type: Array,
28
+ required: false,
29
+ allowed_empty: true,
30
+ each_element_is: NAT_RULE
31
+ }
32
+ }
33
+ }
34
+ end
35
+ end
@@ -0,0 +1,6 @@
1
+ cat <<EOF >fog_integration_test.config
2
+ default:
3
+ vcloud_director_username: '$API_USERNAME'
4
+ vcloud_director_password: '$API_PASSWORD'
5
+ vcloud_director_host: '$API_HOST'
6
+ EOF
@@ -0,0 +1,11 @@
1
+ class ErbHelper
2
+ def self.convert_erb_template_to_yaml test_namespace, input_erb_config
3
+ input_erb_config = input_erb_config
4
+ e = ERB.new(File.open(input_erb_config).read)
5
+ output_yaml_config = File.join(File.dirname(input_erb_config), "output_#{Time.now.strftime('%s')}.yaml")
6
+ File.open(output_yaml_config, 'w') { |f|
7
+ f.write e.result(OpenStruct.new(test_namespace).instance_eval { binding })
8
+ }
9
+ output_yaml_config
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ ---
2
+ gateway: <%= edge_gateway_name %>
3
+ firewall_service:
4
+ policy: drop
5
+ log_default_action: true
6
+ firewall_rules:
7
+ - enabled: true
8
+ description: 'A rule'
9
+ policy: allow
10
+ protocols: 'tcp'
11
+ destination_port_range: Any
12
+ destination_ip: 10.10.1.2
13
+ source_port_range: Any
14
+ source_ip: 192.0.2.2
15
+ - enabled: true
16
+ destination_ip: '10.10.1.3-10.10.1.5'
17
+ source_ip: 192.0.2.2/24
@@ -0,0 +1,17 @@
1
+ ---
2
+ gateway: <%= edge_gateway_name %>
3
+ firewall_service:
4
+ policy: drop
5
+ log_default_action: true
6
+ firewall_rules:
7
+ - enabled: true
8
+ description: 'A rule'
9
+ policy: allow
10
+ protocols: 'tcp'
11
+ destination_port_range: Any
12
+ destination_ip: 10.10.1.2
13
+ source_port_range: Any
14
+ source_ip: 192.0.2.2
15
+ - enabled: true
16
+ destination_ip: '10.10.1.3-10.10.1.6'
17
+ source_ip: 192.0.2.2/24