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
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ *.gem
2
+ *.rbc
3
+ *.swp
4
+ *.un~
5
+ vcloud_env.sh
6
+ replace_variables.sh
7
+ /.bundle/
8
+ /.ruby-version
9
+ /Gemfile.lock
10
+ /bundle/
11
+ /pkg/
12
+ vendor/
13
+ coverage/
14
+ results.html
15
+ fog_integration_test.config
16
+ .idea
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ if ENV['VCLOUD_CORE_DEV_MASTER']
6
+ gem 'vcloud-core', :git => 'git@github.com:alphagov/vcloud-core.git', :branch => 'master'
7
+ elsif ENV['VCLOUD_CORE_DEV_LOCAL']
8
+ gem 'vcloud-core', :path => '../vcloud-core'
9
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 HM Government (Government Digital Service)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,160 @@
1
+ # vCloud Edge Gateway
2
+
3
+ vCloud Edge Gateway is a tool that supports automated provisiong of a VMware vCloud Edge Gateway. It depends on [vCloud Core](https://github.com/alphagov/vcloud-core) and uses Fog under the hood.
4
+
5
+
6
+ #Configure edge gateway services
7
+
8
+ You can configure following services on an existing edgegateway using fog.
9
+ - FirewallService
10
+ - NatService
11
+ - LoadBalancerService
12
+
13
+ ###How to configure:
14
+
15
+ ```ruby
16
+ require 'fog'
17
+ vcloud = Fog::Compute::VcloudDirector.new
18
+ vcloud.post_configure_edge_gateway_services edge_gateway_id, configuration
19
+ vcloud.process_task(task.body)
20
+ ```
21
+
22
+ The Configuration contain definitions of any of the services listed.Details of service configurations may vary,
23
+ but the mechanism is the same for updating any Edge Gateway service.<br/>You can include one or more services when you configure an Edge Gateway.
24
+
25
+ ###Examples:
26
+
27
+ Service examples, to be used in place of the `configuration` object above.
28
+
29
+ Firewall:
30
+ ```ruby
31
+ configuration = {
32
+ :FirewallService => {
33
+ :IsEnabled => true,
34
+ :DefaultAction => 'allow',
35
+ :LogDefaultAction => false,
36
+ :FirewallRule => [
37
+ {
38
+ :Policy => 'allow',
39
+ :Description => 'description',
40
+ :Protocols => {:Tcp => true},
41
+ :Port => 22,
42
+ :DestinationPortRange => 22,
43
+ :DestinationIp => 'Internal',
44
+ :SourcePort => 22,
45
+ :SourceIp => 'External',
46
+ :SourcePortRange => '22'
47
+ }
48
+ ]
49
+ }
50
+ }
51
+ ```
52
+
53
+ Load balancer:
54
+ ```ruby
55
+ configuration = {
56
+ :LoadBalancerService => {
57
+ :IsEnabled => "true",
58
+ :Pool => [
59
+ {
60
+ :Name => 'web-app',
61
+ :ServicePort => [
62
+ {
63
+ :IsEnabled => "true",
64
+ :Protocol => "HTTP",
65
+ :Algorithm => "ROUND_ROBIN",
66
+ :Port => 80,
67
+ :HealthCheckPort => 80,
68
+ :HealthCheck => {
69
+ :Mode => "HTTP", :HealthThreshold => 1, :UnhealthThreshold => 6, :Interval => 20, :Timeout => 25
70
+ }
71
+ },
72
+ {
73
+ :IsEnabled => true,
74
+ :Protocol => "HTTPS",
75
+ :Algorithm => "ROUND_ROBIN",
76
+ :Port => 443,
77
+ :HealthCheckPort => 443,
78
+ :HealthCheck => {
79
+ :Mode => "SSL", :HealthThreshold => 1, :UnhealthThreshold => 6, :Interval => 20, :Timeout => 25
80
+ }
81
+ }
82
+ ],
83
+ :Member => [
84
+ {
85
+ :IpAddress => "192.0.2.0",
86
+ :Weight => 1,
87
+ :ServicePort => [
88
+ {:Protocol => "HTTP", :Port => 80, :HealthCheckPort => 80}
89
+ ]
90
+ }
91
+ ]
92
+ }
93
+ ],
94
+ :VirtualServer => [
95
+ {
96
+ :IsEnabled => "true",
97
+ :Name => "app1",
98
+ :Description => "app1",
99
+ :Interface => {:name => "Default", :href => "https://vmware.api.net/api/admin/network/2ad93597-7b54-43dd-9eb1-631dd337e5a7"},
100
+ :IpAddress => '192.0.2.0',
101
+ :ServiceProfile => [
102
+ {:IsEnabled => "true", :Protocol => "HTTP", :Port => 80, :Persistence => {:Method => ""}},
103
+ {:IsEnabled => "true", :Protocol => "HTTPS", :Port => 443, :Persistence => {:Method => ""}}
104
+ ],
105
+ :Logging => false,
106
+ :Pool => 'web-app'
107
+ }
108
+ ]
109
+ }
110
+ }
111
+ ```
112
+
113
+ Nat:
114
+ ```ruby
115
+ configuration = {
116
+ :NatService => {
117
+ :IsEnabled => true,
118
+ :nat_type => 'ipTranslation',
119
+ :Policy => 'allowTrafficIn',
120
+ :NatRule => [
121
+ {
122
+ :Description => 'a snat rule',
123
+ :RuleType => 'SNAT',
124
+ :IsEnabled => true,
125
+ :Id => '65538',
126
+ :GatewayNatRule => {
127
+ :Interface => {
128
+ :name => 'nft00001',
129
+ :href => 'https://vmware.api.net/api/admin/network/44265cc3-6d63-4ea9-ac72-4905b5aa6111'
130
+ },
131
+ :OriginalIp => "192.0.2.0",
132
+ :TranslatedIp => "203.0.113.10"
133
+ }
134
+ },
135
+ {
136
+ :Description => 'a dnat rule',
137
+ :RuleType => 'DNAT',
138
+ :IsEnabled => true,
139
+ :Id => '65539',
140
+ :GatewayNatRule =>
141
+ {
142
+ :Interface => {
143
+ :name => 'nft00001',
144
+ :href => 'https://vmware.api.net/api/admin/network/44265cc3-6d63-4ea9-ac72-4905b5aa6111'
145
+ },
146
+ :Protocol => 'tcp',
147
+ :OriginalIp => "203.0.113.10",
148
+ :OriginalPort => 22,
149
+ :TranslatedIp => "192.0.2.0",
150
+ :TranslatedPort => 22
151
+ },
152
+ }
153
+ ]
154
+ }
155
+ }
156
+ ```
157
+
158
+ ###Debug
159
+
160
+ Set environment variable DEBUG=true to see fog debug info.
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec) do |task|
5
+ # Set a bogus Fog credential, otherwise it's possible for the unit
6
+ # tests to accidentially run (and succeed against!) an actual
7
+ # environment, if Fog connection is not stubbed correctly.
8
+ ENV['FOG_CREDENTIAL'] = 'random_nonsense_owiejfoweijf'
9
+ ENV['COVERAGE'] = 'true'
10
+ task.pattern = FileList['spec/vcloud/**/*_spec.rb']
11
+ end
12
+
13
+ task :default => [:spec]
14
+
15
+ RSpec::Core::RakeTask.new('integration') do |t|
16
+ t.pattern = FileList['spec/integration/**/*_spec.rb']
17
+ end
18
+
19
+ require "gem_publisher"
20
+ task :publish_gem do |t|
21
+ gem = GemPublisher.publish_if_updated("vcloud-edge_gateway.gemspec", :rubygems)
22
+ puts "Published #{gem}" if gem
23
+ end
data/bin/vcloud-edge ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'rubygems'
5
+ gem 'vcloud-edge_gateway'
6
+ rescue LoadError
7
+ end
8
+
9
+ require 'vcloud/edge_gateway'
10
+
11
+ print "Test message just to string this together"
12
+ print "No CLI for vCloud Edge Gateway yet"
data/jenkins.sh ADDED
@@ -0,0 +1,11 @@
1
+ #!/bin/bash -x
2
+ set -e
3
+ bundle install --path "${HOME}/bundles/${JOB_NAME}"
4
+ bundle exec rake
5
+
6
+ ./scripts/generate_fog_conf_file.sh
7
+ export FOG_RC=fog_integration_test.config
8
+ bundle exec rake integration
9
+ rm fog_integration_test.config
10
+
11
+ bundle exec rake publish_gem
@@ -0,0 +1,27 @@
1
+ require 'yaml'
2
+ require 'json'
3
+
4
+ module Vcloud
5
+ class ConfigLoader
6
+
7
+ def load_config(config_file, schema = nil)
8
+ input_config = YAML::load(File.open(config_file))
9
+
10
+ # There is no way in YAML or Ruby to symbolize keys in a hash
11
+ json_string = JSON.generate(input_config)
12
+ config = JSON.parse(json_string, :symbolize_names => true)
13
+
14
+ if schema
15
+ validation = ConfigValidator.validate(:base, config, schema)
16
+ unless validation.valid?
17
+ validation.errors.each do |error|
18
+ Vcloud::EdgeGateway.logger.fatal(error)
19
+ end
20
+ raise("Supplied configuration does not match supplied schema")
21
+ end
22
+ end
23
+ config
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,207 @@
1
+ require 'ipaddr'
2
+
3
+ module Vcloud
4
+ class ConfigValidator
5
+
6
+ attr_reader :key, :data, :schema, :type, :errors
7
+
8
+ VALID_ALPHABETICAL_VALUES_FOR_IP_RANGE = %w(Any external internal)
9
+
10
+ def initialize(key, data, schema)
11
+ raise "Nil schema" unless schema
12
+ raise "Invalid schema" unless schema.key?(:type)
13
+ @type = schema[:type].to_s.downcase
14
+ @errors = []
15
+ @data = data
16
+ @schema = schema
17
+ @key = key
18
+ validate
19
+ end
20
+
21
+ def valid?
22
+ @errors.empty?
23
+ end
24
+
25
+ def self.validate(key, data, schema)
26
+ new(key, data, schema)
27
+ end
28
+
29
+ private
30
+
31
+ def validate
32
+ self.send("validate_#{type}".to_sym)
33
+ end
34
+
35
+ def validate_string
36
+ unless @data.is_a? String
37
+ errors << "#{key}: #{@data} is not a string"
38
+ return
39
+ end
40
+ return unless check_emptyness_ok
41
+ return unless check_matcher_matches
42
+ end
43
+
44
+ def validate_string_or_number
45
+ unless data.is_a?(String) || data.is_a?(Numeric)
46
+ @errors << "#{key}: #{@data} is not a string_or_number"
47
+ return
48
+ end
49
+ end
50
+
51
+ def validate_ip_address
52
+ unless data.is_a?(String)
53
+ @errors << "#{key}: #{@data} is not a valid ip_address"
54
+ return
55
+ end
56
+ @errors << "#{key}: #{@data} is not a valid ip_address" unless valid_ip_address?(data)
57
+ end
58
+
59
+ def validate_ip_address_range
60
+ unless data.is_a?(String)
61
+ @errors << "#{key}: #{@data} is not a valid IP address range. Valid values can be IP address, CIDR, IP range, 'Any','internal' and 'external'."
62
+ return
63
+ end
64
+ valid = valid_cidr_or_ip_address? || valid_alphabetical_ip_range? || valid_ip_range?
65
+ @errors << "#{key}: #{@data} is not a valid IP address range. Valid values can be IP address, CIDR, IP range, 'Any','internal' and 'external'." unless valid
66
+ end
67
+
68
+ def valid_cidr_or_ip_address?
69
+ begin
70
+ ip = IPAddr.new(data)
71
+ ip.ipv4?
72
+ rescue ArgumentError
73
+ false
74
+ end
75
+ end
76
+
77
+ def valid_alphabetical_ip_range?
78
+ VALID_ALPHABETICAL_VALUES_FOR_IP_RANGE.include?(data)
79
+ end
80
+
81
+ def valid_ip_address? ip_address
82
+ begin
83
+ #valid formats recognized by IPAddr are : “address”, “address/prefixlen” and “address/mask”.
84
+ # Attribute like member_ip in case of load-balancer is an "address"
85
+ # and we should not accept “address/prefixlen” and “address/mask” for such fields.
86
+ ip = IPAddr.new(ip_address)
87
+ ip.ipv4? && !ip_address.include?('/')
88
+ rescue ArgumentError
89
+ false
90
+ end
91
+ end
92
+
93
+ def valid_ip_range?
94
+ range_parts = data.split('-')
95
+ return false if range_parts.size != 2
96
+ start_address = range_parts.first
97
+ end_address = range_parts.last
98
+ valid_ip_address?(start_address) && valid_ip_address?(end_address) &&
99
+ valid_start_and_end_address_combination?(end_address, start_address)
100
+ end
101
+
102
+ def valid_start_and_end_address_combination?(end_address, start_address)
103
+ IPAddr.new(start_address) < IPAddr.new(end_address)
104
+ end
105
+
106
+ def validate_hash
107
+ unless data.is_a? Hash
108
+ @errors << "#{key}: is not a hash"
109
+ return
110
+ end
111
+ return unless check_emptyness_ok
112
+ check_for_unknown_parameters
113
+ if schema.key?(:internals)
114
+ internals = schema[:internals]
115
+ internals.each do |param_key,param_schema|
116
+ check_hash_parameter(param_key, param_schema)
117
+ end
118
+ end
119
+ end
120
+
121
+ def validate_array
122
+ unless data.is_a? Array
123
+ @errors << "#{key} is not an array"
124
+ return
125
+ end
126
+ return unless check_emptyness_ok
127
+ if schema.key?(:each_element_is)
128
+ element_schema = schema[:each_element_is]
129
+ data.each do |element|
130
+ sub_validator = ConfigValidator.validate(key, element, element_schema)
131
+ unless sub_validator.valid?
132
+ @errors = errors + sub_validator.errors
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ def validate_enum
139
+ unless (acceptable_values = schema[:acceptable_values]) && acceptable_values.is_a?(Array)
140
+ raise "Must set :acceptable_values for type 'enum'"
141
+ end
142
+ unless acceptable_values.include?(data)
143
+ acceptable_values_string = acceptable_values.collect {|v| "'#{v}'" }.join(', ')
144
+ @errors << "#{key}: #{@data} is not a valid value. Acceptable values are #{acceptable_values_string}."
145
+ end
146
+ end
147
+
148
+ def validate_boolean
149
+ unless [true, false].include?(data)
150
+ @errors << "#{key}: #{data} is not a valid boolean value."
151
+ end
152
+ end
153
+
154
+ def check_emptyness_ok
155
+ unless schema.key?(:allowed_empty) && schema[:allowed_empty]
156
+ if data.empty?
157
+ @errors << "#{key}: cannot be empty #{type}"
158
+ return false
159
+ end
160
+ end
161
+ true
162
+ end
163
+
164
+ def check_matcher_matches
165
+ return unless regex = schema[:matcher]
166
+ raise "#{key}: #{regex} is not a Regexp" unless regex.is_a? Regexp
167
+ unless data =~ regex
168
+ @errors << "#{key}: #{data} does not match"
169
+ return false
170
+ end
171
+ true
172
+ end
173
+
174
+ def check_hash_parameter(sub_key, sub_schema)
175
+ if sub_schema.key?(:required) && sub_schema[:required] == false
176
+ # short circuit out if we do not have the key, but it's not required.
177
+ return true unless data.key?(sub_key)
178
+ end
179
+ unless data.key?(sub_key)
180
+ @errors << "#{key}: missing '#{sub_key}' parameter"
181
+ return false
182
+ end
183
+ sub_validator = ConfigValidator.validate(
184
+ sub_key,
185
+ data[sub_key],
186
+ sub_schema
187
+ )
188
+ unless sub_validator.valid?
189
+ @errors = errors + sub_validator.errors
190
+ end
191
+ end
192
+
193
+ def check_for_unknown_parameters
194
+ unless internals = schema[:internals]
195
+ # if there are no parameters specified, then assume all are ok.
196
+ return true
197
+ end
198
+ if schema[:permit_unknown_parameters]
199
+ return true
200
+ end
201
+ data.keys.each do |k|
202
+ @errors << "#{key}: parameter '#{k}' is invalid" unless internals[k]
203
+ end
204
+ end
205
+
206
+ end
207
+ end
@@ -0,0 +1,17 @@
1
+ module Vcloud
2
+ module EdgeGateway
3
+ class ConfigurationDiffer
4
+
5
+ def initialize local, remote
6
+ @local = local
7
+ @remote = remote
8
+ end
9
+
10
+ def diff
11
+ ( @local == @remote ) ? [] : HashDiff.diff(@local, @remote)
12
+ end
13
+
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,63 @@
1
+ module Vcloud
2
+ module EdgeGateway
3
+ module ConfigurationGenerator
4
+ class FirewallService
5
+
6
+ def generate_fog_config(input_config)
7
+ if input_config
8
+ firewall_service = {}
9
+ firewall_service[:IsEnabled] = input_config.key?(:enabled) ? input_config[:enabled].to_s : 'true'
10
+ firewall_service[:DefaultAction] = input_config.key?(:policy) ? input_config[:policy] : "drop"
11
+ firewall_service[:LogDefaultAction] = input_config.key?(:log_default_action) ? input_config[:log_default_action].to_s : 'false'
12
+ firewall_service[:FirewallRule] = populate_firewall_rules(input_config[:firewall_rules]) if input_config.key?(:firewall_rules)
13
+ firewall_service
14
+ end
15
+ end
16
+
17
+ private
18
+ def populate_firewall_rules rules
19
+ i = ID_RANGES::FIREWALL_SERVICE[:min]
20
+ rules.collect do |rule|
21
+ new_rule = {}
22
+ new_rule[:Id] = rule.key?(:id) ? rule[:id] : i.to_s
23
+ new_rule[:IsEnabled] = rule.key?(:enabled) ? rule[:enabled].to_s : 'true'
24
+ new_rule[:MatchOnTranslate] = rule.key?(:match_on_translate) ? rule[:match_on_translate].to_s : 'false'
25
+ new_rule[:Description] = rule.key?(:description) ? rule[:description] : ""
26
+ new_rule[:Policy] = rule.key?(:policy) ? rule[:policy] : "allow"
27
+ new_rule[:Protocols] = rule.key?(:protocols) ? handle_protocols(rule[:protocols]) : {Tcp: 'true'}
28
+ new_rule[:DestinationPortRange] = rule.key?(:destination_port_range) ? rule[:destination_port_range] : 'Any'
29
+ new_rule[:Port] = handle_vmware_port_deprecation_behaviour(rule[:destination_port_range])
30
+ new_rule[:DestinationIp] = rule[:destination_ip]
31
+ new_rule[:SourcePortRange] = rule.key?(:source_port_range) ? rule[:source_port_range] : 'Any'
32
+ new_rule[:SourcePort] = handle_vmware_port_deprecation_behaviour(rule[:source_port_range])
33
+ new_rule[:SourceIp] = rule[:source_ip]
34
+ new_rule[:EnableLogging] = rule.key?(:enable_logging) ? rule[:enable_logging].to_s : 'false'
35
+ i += 1
36
+ new_rule
37
+ end
38
+ end
39
+
40
+ def handle_vmware_port_deprecation_behaviour(port_spec)
41
+ (port_spec.to_s =~ /^\d+$/) ? port_spec.to_s : '-1'
42
+ end
43
+
44
+ def handle_protocols(protocols)
45
+ case protocols.downcase
46
+ when "tcp+udp"
47
+ {Tcp: 'true', Udp: 'true'}
48
+ when "udp"
49
+ {Udp: 'true'}
50
+ when "tcp"
51
+ {Tcp: 'true'}
52
+ when "icmp"
53
+ {Icmp: 'true'}
54
+ when "any"
55
+ {Tcp: 'true', Udp: 'true', Icmp: 'true'}
56
+ end
57
+ end
58
+
59
+ end
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,10 @@
1
+ module Vcloud
2
+ module EdgeGateway
3
+ module ConfigurationGenerator
4
+ module ID_RANGES
5
+ FIREWALL_SERVICE = {min: 1, max: 65536}
6
+ NAT_SERVICE = {min: 65537, max: 131072}
7
+ end
8
+ end
9
+ end
10
+ end