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