vcloud-network-configurator 0.1.0
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.
- data/.gitignore +2 -0
- data/Gemfile +4 -0
- data/README.md +116 -0
- data/Rakefile +25 -0
- data/bin/vcloud_configure_edge_gateway +5 -0
- data/docs/find_network_url.md +56 -0
- data/docs/find_organisation_edgegateway_uuid.md +58 -0
- data/jenkins.sh +6 -0
- data/lib/component/firewall.rb +82 -0
- data/lib/component/load_balancer.rb +181 -0
- data/lib/component/nat.rb +73 -0
- data/lib/vcloud_network_configurator.rb +64 -0
- data/lib/vcloud_network_configurator/configure_task.rb +22 -0
- data/lib/vcloud_network_configurator/edge_gateway.rb +51 -0
- data/lib/vcloud_network_configurator/vcloud_auth_request.rb +39 -0
- data/lib/vcloud_network_configurator/vcloud_check_for_configure_task_request.rb +26 -0
- data/lib/vcloud_network_configurator/vcloud_configure_request.rb +51 -0
- data/lib/vcloud_network_configurator/vcloud_settings.rb +22 -0
- data/lib/vcloud_network_configurator/version.rb +1 -0
- data/spec/component/firewall.xml +45 -0
- data/spec/component/firewall_spec.rb +115 -0
- data/spec/component/lb.xml +567 -0
- data/spec/component/load_balancer_spec.rb +67 -0
- data/spec/component/nat.xml +146 -0
- data/spec/component/nat_spec.rb +28 -0
- data/spec/integration/authorization_failed_spec.rb +26 -0
- data/spec/integration/happy_path_firewall_spec.rb +74 -0
- data/spec/integration/happy_path_loadbalancer_spec.rb +173 -0
- data/spec/integration/happy_path_nat_spec.rb +78 -0
- data/spec/integration/test_data/happy_path_auth_response.xml +30 -0
- data/spec/integration/test_data/rules_dir/common_firewall.rb +6 -0
- data/spec/integration/test_data/rules_dir/common_lb.rb +10 -0
- data/spec/integration/test_data/rules_dir/common_nat.rb +0 -0
- data/spec/integration/test_data/rules_dir/preview/firewall.rb +0 -0
- data/spec/integration/test_data/rules_dir/preview/interfaces.yaml +2 -0
- data/spec/integration/test_data/rules_dir/preview/lb.rb +0 -0
- data/spec/integration/test_data/rules_dir/preview/nat.rb +4 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/vcloud_network_configurator/configure_task_spec.rb +59 -0
- data/spec/vcloud_network_configurator/edge_gateway_spec.rb +41 -0
- data/spec/vcloud_network_configurator/vcloud_auth_request_spec.rb +20 -0
- data/spec/vcloud_network_configurator/vcloud_settings_spec.rb +19 -0
- data/vcloud-network-configurator.gemspec +33 -0
- metadata +212 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
# Vcloud Network Configurator
|
2
|
+
|
3
|
+
This is ruby gem which provides a dsl to configure firewall, nat and
|
4
|
+
loadbalancer rules. It is a wrapper around the network components of
|
5
|
+
vcloud api.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
gem install vcloud-network-configurator
|
10
|
+
|
11
|
+
* Note: It is work in progress, and currently you would have to build
|
12
|
+
them gem locally using the following commands
|
13
|
+
|
14
|
+
git clone git@github.com:alphagov/vcloud-network-configurator.git
|
15
|
+
gem build vcloud-network-configurator.gemspec
|
16
|
+
gem install ./vcloud-network-configurator-0.1.0.gem
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
Usage: vcloud_configure_edge_gateway [options] API_URL
|
21
|
+
-u, --username=U Vcloud Username
|
22
|
+
-p, --password=P Vcloud Password
|
23
|
+
-e, --env=E Environment: preview | staging | production
|
24
|
+
-U, --organization-edgegateway-uuid=U UID: This is required to configure edgegateway services. For more info refer to
|
25
|
+
docs/find_organisation_edgegateway_uuid
|
26
|
+
-c, --component=c Environment: lb|firewall|nat
|
27
|
+
-o, --organization=o Organization: optional. Will default to environment
|
28
|
+
-d, --rule-directory=d Rules Directory: From where to read the NAT/Firewal/LB rules
|
29
|
+
|
30
|
+
Note: organization maps to the organization name in vcloud. Whereas,
|
31
|
+
environment maps to your internal environment reference (e.g.
|
32
|
+
preview, qa, staging, production, etc)
|
33
|
+
|
34
|
+
### Example
|
35
|
+
|
36
|
+
vcloud_configure_edge_gateway -u username -p password -e preview -U 1yenz127ynz1872eyz12yz817e -c firewall -o development -d . http://vcloud.vendor.com/api
|
37
|
+
|
38
|
+
### Rules Directory
|
39
|
+
|
40
|
+
A particular rules directory structure could be as follows.
|
41
|
+
|
42
|
+
.
|
43
|
+
├── Gemfile
|
44
|
+
├── Gemfile.lock
|
45
|
+
├── common_firewall.rb
|
46
|
+
├── common_lb.rb
|
47
|
+
├── common_nat.rb
|
48
|
+
├── env1
|
49
|
+
│ ├── firewall.rb
|
50
|
+
│ ├── interfaces.yaml
|
51
|
+
│ ├── lb.rb
|
52
|
+
│ └── nat.rb
|
53
|
+
├── env2
|
54
|
+
├── firewall.rb
|
55
|
+
├── interfaces.yaml
|
56
|
+
├── lb.rb
|
57
|
+
└── nat.rb
|
58
|
+
|
59
|
+
* Here each environment represent a separate organisation with your vcloud
|
60
|
+
vendor (eg qa, staging, production). These could have specific rules for nat,
|
61
|
+
firewall. Also these can have common firewall rules which could be shared
|
62
|
+
across all environments. A common example of such a situation is internal
|
63
|
+
network firewall rules are usually shared across environments, whereas
|
64
|
+
external network firewall rules would be different for all environment.
|
65
|
+
|
66
|
+
* Specific network rules => `env1/firewall.rb`, `env1/nat.rb`, `env1/lb.rb`
|
67
|
+
* Common network rules => `./common_firewall.rb`, `./common_lb.rb`, `./common_lb.rb`
|
68
|
+
|
69
|
+
* interfaces.yaml file:
|
70
|
+
To find the urls for network, follow the document at
|
71
|
+
`docs/find_network_url`
|
72
|
+
|
73
|
+
interfaces:
|
74
|
+
Network-1: "https://localhost:4567/api/admin/network/<vdc-network-uuid>"
|
75
|
+
Network-2: "https://localhost:4567/api/admin/network/<vdc-network-uuid>"
|
76
|
+
|
77
|
+
### DSL
|
78
|
+
|
79
|
+
#### Firewall
|
80
|
+
|
81
|
+
firewall do
|
82
|
+
rule "<description>" do
|
83
|
+
source :ip => "172.10.0.0/8"
|
84
|
+
destination :ip => "172.10.0.5", :port => 4567
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
#### NAT
|
89
|
+
|
90
|
+
nat do
|
91
|
+
snat :interface => "<key-from-interfaces.rb>", :original => { :ip => "internal-ip" }, :translated => { :ip => "external-ip" }, :desc => "description"
|
92
|
+
dnat :interface => "<key-from-interfaces.rb>", :original => { :ip => "external-ip", :port => 22 }, :translated => { :ip => "internal-ip", :port => 22 }, :desc => "SSH"
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
#### Load Balancer
|
97
|
+
|
98
|
+
load_balancer do
|
99
|
+
configure "description-1" do
|
100
|
+
pool ["<ip-1>", "<ip-2>"] do
|
101
|
+
http
|
102
|
+
https
|
103
|
+
end
|
104
|
+
|
105
|
+
virtual_server :name => "description-1", :interface => "<key-from-interfaces.rb>", :ip => "<vse-ip>"
|
106
|
+
end
|
107
|
+
|
108
|
+
configure "description-2" do
|
109
|
+
pool ["<ip-1>", "<ip-2>", "<ip-3>"] do
|
110
|
+
http :port => 8080, :health_check_path => "</router/healthcheck>"
|
111
|
+
https
|
112
|
+
end
|
113
|
+
|
114
|
+
virtual_server :name => "description-2", :interface => "<key-from-interfaces.rb>", :ip => "<vse-ip>"
|
115
|
+
end
|
116
|
+
end
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
require "gem_publisher"
|
5
|
+
|
6
|
+
RSpec::Core::RakeTask.new(:spec) do |task|
|
7
|
+
task.pattern = FileList.new('spec/**/*_spec.rb') do |file|
|
8
|
+
file.exclude(/integration/)
|
9
|
+
end
|
10
|
+
task.rspec_opts = ['--color']
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec::Core::RakeTask.new(:integration) do |task|
|
14
|
+
task.pattern = FileList['spec/integration/*_spec.rb']
|
15
|
+
task.rspec_opts = ['--color']
|
16
|
+
end
|
17
|
+
|
18
|
+
task :default => [:spec]
|
19
|
+
|
20
|
+
desc "Publish gem to RubyGems.org"
|
21
|
+
task :publish_gem do |t|
|
22
|
+
gem = GemPublisher.publish_if_updated("vcloud-network-configurator.gemspec", :rubygems)
|
23
|
+
puts "Published #{gem}" if gem
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# How to find Network UUID for interfaces.yaml
|
2
|
+
|
3
|
+
## Steps
|
4
|
+
|
5
|
+
* vcloud authorization
|
6
|
+
|
7
|
+
curl -v -X POST -d '' -H "Accept: application/*+xml;version=5.1"
|
8
|
+
-u "{username}@vcloud-org-name:**********"
|
9
|
+
https://vendor-api-url.net/sessions
|
10
|
+
|
11
|
+
|
12
|
+
The above returns the following information in response
|
13
|
+
`x-cloud-authorization` and
|
14
|
+
`<Link rel="down" type="application/vnd.vmware.vcloud.orgList+xml" href="https://vendor-api-url.net/org/"/>`
|
15
|
+
|
16
|
+
|
17
|
+
* List organisations
|
18
|
+
|
19
|
+
curl -v --insecure
|
20
|
+
-H "x-vcloud-authorization: {x-vcloud-auth-code}"
|
21
|
+
-H "Accept: application/*+xml;version=5.1"
|
22
|
+
"https://vendor-api-url.net/org/"
|
23
|
+
|
24
|
+
|
25
|
+
This gives the list of organizations you have access to, and you can choose the one you need by using the name attribute `<Org type="application/vnd.vmware.vcloud.org+xml" name="ORG-NAME" href="https://vendor-api-url.net/org/{org-code}"/>`
|
26
|
+
|
27
|
+
* Get details of the organisation
|
28
|
+
|
29
|
+
curl -v --insecure -H "x-vcloud-authorization: {x-vcloud-auth-code}"
|
30
|
+
-H "Accept: application/*+xml;version=5.1"
|
31
|
+
"https://vendor-api-url.net/org/{org-code}"
|
32
|
+
|
33
|
+
* This also gives details about various vdc. We would need the one for management vdc:
|
34
|
+
|
35
|
+
<Link rel="down" type="application/vnd.vmware.vcloud.vdc+xml"
|
36
|
+
name="Management - GDS Development (SL1)"
|
37
|
+
href="https://vendor-api-url.net/vdc/{vdc-uuid}"/>
|
38
|
+
|
39
|
+
* Get vdc details
|
40
|
+
|
41
|
+
curl -v --insecure -H "x-vcloud-authorization: {x-vcloud-auth-code}"
|
42
|
+
-H "Accept: application/*+xml;version=5.1"
|
43
|
+
"https://vendor-api-url.net/vdc/{vdc-uuid}
|
44
|
+
|
45
|
+
* This would provide you with available networks. From which you
|
46
|
+
can use the name and href attributes for adding to your
|
47
|
+
interfaces.yaml
|
48
|
+
|
49
|
+
<AvailableNetworks>
|
50
|
+
<Network type="application/vnd.vmware.vcloud.network+xml" name="NetworkTest2"
|
51
|
+
href="https:///vendor-api-url.net/network/{network-uuid-2}"/>
|
52
|
+
<Network type="application/vnd.vmware.vcloud.network+xml" name="NetworkTest"
|
53
|
+
href="https:///vendor-api-url.net/network/{network-uuid-1}"/>
|
54
|
+
</AvailableNetworks>
|
55
|
+
|
56
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# How to find Organisation Edgegateway UUID
|
2
|
+
|
3
|
+
##Steps:
|
4
|
+
|
5
|
+
* vcloud authorization
|
6
|
+
|
7
|
+
curl -v -X POST -d '' -H "Accept: application/*+xml;version=5.1"
|
8
|
+
-u "{username}@vcloud-org-name:**********"
|
9
|
+
https://vendor-api-url.net/sessions
|
10
|
+
|
11
|
+
|
12
|
+
The above returns the following information in response
|
13
|
+
`x-cloud-authorization` and
|
14
|
+
`<Link rel="down" type="application/vnd.vmware.vcloud.orgList+xml" href="https://vendor-api-url.net/org/"/>`
|
15
|
+
|
16
|
+
|
17
|
+
* List organisations
|
18
|
+
|
19
|
+
curl -v --insecure
|
20
|
+
-H "x-vcloud-authorization: {x-vcloud-auth-code}"
|
21
|
+
-H "Accept: application/*+xml;version=5.1"
|
22
|
+
"https://vendor-api-url.net/org/"
|
23
|
+
|
24
|
+
|
25
|
+
This gives the list of organizations you have access to, and you can choose the one you need by using the name attribute `<Org type="application/vnd.vmware.vcloud.org+xml" name="ORG-NAME" href="https://vendor-api-url.net/org/{org-code}"/>`
|
26
|
+
|
27
|
+
* Get details of the organisation
|
28
|
+
|
29
|
+
curl -v --insecure -H "x-vcloud-authorization: {x-vcloud-auth-code}"
|
30
|
+
-H "Accept: application/*+xml;version=5.1"
|
31
|
+
"https://vendor-api-url.net/org/{org-code}"
|
32
|
+
|
33
|
+
* This also gives details about various vdc. We would need the one for management vdc:
|
34
|
+
|
35
|
+
<Link rel="down" type="application/vnd.vmware.vcloud.vdc+xml"
|
36
|
+
name="Management - GDS Development (SL1)"
|
37
|
+
href="https://vendor-api-url.net/vdc/{org-code}"/>
|
38
|
+
|
39
|
+
* Retrieve edgegateway record
|
40
|
+
|
41
|
+
curl -v --insecure -H "x-vcloud-authorization: {x-vcloud-auth-code}="
|
42
|
+
-H "Accept: application/*+xml;version=5.1"
|
43
|
+
"https://vendor-api-url.net/admin/vdc/{management-edgegateway-uuid}/edgeGateways"
|
44
|
+
|
45
|
+
* Response of the above is (from which you would need the id in the href attribute):
|
46
|
+
|
47
|
+
<EdgeGatewayRecord vdc="https://vendor-api-url.net/vdc/{management-edgegateway-uuid}"
|
48
|
+
numberOfOrgNetworks="8" numberOfExtNetworks="1"
|
49
|
+
name="GDS Development Gateway" isBusy="false" haStatus="UP" gatewayStatus="READY"
|
50
|
+
href="https://vendor-api-url.net/admin/edgeGateway/{id}"
|
51
|
+
isSyslogServerSettingInSync="true" taskStatus="success"
|
52
|
+
taskOperation="networkConfigureEdgeGatewayServices"
|
53
|
+
task="https://vendor-api-url.net/task/***" taskDetails=" "/>
|
54
|
+
|
55
|
+
*e.g. https://vendor-api-url.net/admin/edgeGateway/{id}*
|
56
|
+
|
57
|
+
|
58
|
+
|
data/jenkins.sh
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
module Component
|
5
|
+
class Firewall
|
6
|
+
attr_reader :rules
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@rules = []
|
10
|
+
@count = 0
|
11
|
+
end
|
12
|
+
|
13
|
+
def rule(description, options = {}, &block)
|
14
|
+
defaults = { :enabled => true, :protocols => [:tcp], :id => @count+=1, :description => description}
|
15
|
+
@current_rule = defaults.merge(options)
|
16
|
+
rules << @current_rule
|
17
|
+
yield
|
18
|
+
ensure
|
19
|
+
@current_rule = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def source(options)
|
23
|
+
@current_rule[:source] = { :port => options[:port] || "Any", :ip => options[:ip] }
|
24
|
+
end
|
25
|
+
|
26
|
+
def destination(options)
|
27
|
+
@current_rule[:destination] = { :port => options[:port], :ip => options[:ip] }
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.reset
|
31
|
+
@firewall = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.instance
|
35
|
+
@firewall ||= Firewall.new
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.generate_xml interfaces
|
39
|
+
Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
40
|
+
xml.EdgeGatewayServiceConfiguration('xmlns' => "http://www.vmware.com/vcloud/v1.5", 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance", 'xsi:schemaLocation' => "http://www.vmware.com/vcloud/v1.5 http://vendor-api-url.net/v1.5/schema/master.xsd") {
|
41
|
+
xml.FirewallService {
|
42
|
+
xml.IsEnabled "true"
|
43
|
+
xml.DefaultAction "drop"
|
44
|
+
xml.LogDefaultAction "false"
|
45
|
+
|
46
|
+
Firewall.instance.rules.each do |rule|
|
47
|
+
xml.FirewallRule {
|
48
|
+
xml.Id rule[:id]
|
49
|
+
xml.IsEnabled rule[:enabled]
|
50
|
+
xml.MatchOnTranslate "false"
|
51
|
+
xml.Description rule[:description]
|
52
|
+
xml.Policy "allow"
|
53
|
+
|
54
|
+
xml.Protocols {
|
55
|
+
rule[:protocols].each do |protocol|
|
56
|
+
xml.send(protocol.to_s.capitalize, true)
|
57
|
+
end
|
58
|
+
}
|
59
|
+
|
60
|
+
if rule[:protocols].first == :icmp
|
61
|
+
xml.IcmpSubType "any"
|
62
|
+
end
|
63
|
+
|
64
|
+
xml.Port rule[:destination][:port] == "Any" ? "-1" : rule[:destination][:port]
|
65
|
+
xml.DestinationPortRange rule[:destination][:port]
|
66
|
+
xml.DestinationIp rule[:destination][:ip]
|
67
|
+
xml.SourcePort rule[:source][:port] == "Any" ? "-1" : rule[:source][:port]
|
68
|
+
xml.SourcePortRange rule[:source][:port]
|
69
|
+
xml.SourceIp rule[:source][:ip]
|
70
|
+
xml.EnableLogging "false"
|
71
|
+
}
|
72
|
+
end
|
73
|
+
}
|
74
|
+
}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def firewall (&block)
|
81
|
+
Component::Firewall.instance.instance_eval(&block)
|
82
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
module Component
|
5
|
+
class LoadBalancer
|
6
|
+
attr_reader :pools, :configurations
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@pools = []
|
10
|
+
@configurations = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def configure(name, &block)
|
14
|
+
@current_configuration = { :name => name, :virtual_servers => [], :pool => nil }
|
15
|
+
@configurations << @current_configuration
|
16
|
+
yield
|
17
|
+
ensure
|
18
|
+
@current_pool = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def virtual_server(options = {})
|
22
|
+
raise "Can't add a virtual server without first having defined a pool" if @current_pool.nil?
|
23
|
+
virtual_server = { :name => options[:name], :pool => @current_pool[:name], :ip => options[:ip], :interface => options[:interface] }
|
24
|
+
@current_configuration[:virtual_servers] << virtual_server
|
25
|
+
end
|
26
|
+
|
27
|
+
def pool(nodes, &block)
|
28
|
+
@current_pool = { :name => "#{@current_configuration[:name]} pool", :ports => [], :nodes => nodes }
|
29
|
+
@current_configuration[:pool] = @current_pool
|
30
|
+
@pools << @current_pool
|
31
|
+
yield
|
32
|
+
end
|
33
|
+
|
34
|
+
def http(options = {})
|
35
|
+
defaults = { :enabled => true, :health_check_path => "/", :port => 80, :health_check_mode => "HTTP" }
|
36
|
+
options = defaults.merge(options)
|
37
|
+
@current_pool[:ports] << { :port => options[:port], :health_check_port => options[:health_check_port],
|
38
|
+
:health_check_path => options[:health_check_path], :enabled => options[:enabled],
|
39
|
+
:type => :http, :health_check_mode=>options[:health_check_mode] }
|
40
|
+
end
|
41
|
+
|
42
|
+
def https(options = {})
|
43
|
+
defaults = { :enabled => true, :health_check_path => "/", :port => 443, :health_check_mode => "SSL" }
|
44
|
+
options = defaults.merge(options)
|
45
|
+
@current_pool[:ports] << { :port => options[:port], :health_check_port => options[:health_check_port],
|
46
|
+
:health_check_path => options[:health_check_path], :enabled => options[:enabled],
|
47
|
+
:type => :https, :health_check_mode => options[:health_check_mode] }
|
48
|
+
end
|
49
|
+
|
50
|
+
def load_balances(port, options = {})
|
51
|
+
defaults = { :enabled => true, :health_check_path => "/" }
|
52
|
+
options = defaults.merge(options)
|
53
|
+
@current_pool[:ports] << { :port => port, :health_check_port => options[:health_check_port], :health_check_path => options[:health_check_path],
|
54
|
+
:enabled => options[:enabled], :type => options[:type] }
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.instance
|
58
|
+
@lb ||= LoadBalancer.new
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.generate_xml interfaces
|
62
|
+
Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
63
|
+
xml.EdgeGatewayServiceConfiguration('xmlns' => "http://www.vmware.com/vcloud/v1.5", 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance", 'xsi:schemaLocation' => "http://www.vmware.com/vcloud/v1.5 http://vendor-api-url.net/v1.5/schema/master.xsd") {
|
64
|
+
xml.LoadBalancerService {
|
65
|
+
xml.IsEnabled 'false'
|
66
|
+
LoadBalancer.instance.pools.each do |pool|
|
67
|
+
xml.Pool {
|
68
|
+
xml.Name pool[:name]
|
69
|
+
|
70
|
+
pool[:ports].each do |port|
|
71
|
+
xml.ServicePort {
|
72
|
+
xml.IsEnabled port[:enabled]
|
73
|
+
xml.Protocol port[:port] == 443 ? "HTTPS" : "HTTP"
|
74
|
+
xml.Algorithm 'ROUND_ROBIN'
|
75
|
+
xml.Port port[:port]
|
76
|
+
|
77
|
+
if port[:health_check_port]
|
78
|
+
xml.HealthCheckPort port[:health_check_port]
|
79
|
+
else
|
80
|
+
xml.HealthCheckPort
|
81
|
+
end
|
82
|
+
|
83
|
+
xml.HealthCheck {
|
84
|
+
xml.Mode port[:health_check_mode]
|
85
|
+
xml.Uri port[:health_check_path]
|
86
|
+
xml.HealthThreshold "2"
|
87
|
+
xml.UnhealthThreshold "3"
|
88
|
+
xml.Interval "5"
|
89
|
+
xml.Timeout "15"
|
90
|
+
}
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
xml.ServicePort {
|
95
|
+
xml.IsEnabled 'false'
|
96
|
+
xml.Protocol "TCP"
|
97
|
+
xml.Algorithm 'ROUND_ROBIN'
|
98
|
+
xml.Port
|
99
|
+
xml.HealthCheckPort
|
100
|
+
xml.HealthCheck {
|
101
|
+
xml.Mode "TCP"
|
102
|
+
xml.HealthThreshold "2"
|
103
|
+
xml.UnhealthThreshold "3"
|
104
|
+
xml.Interval "5"
|
105
|
+
xml.Timeout "15"
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
pool[:nodes].each do |node|
|
110
|
+
xml.Member {
|
111
|
+
xml.IpAddress node
|
112
|
+
xml.Weight "1"
|
113
|
+
|
114
|
+
["HTTP", "HTTPS"].each do |protocol|
|
115
|
+
xml.ServicePort {
|
116
|
+
xml.Protocol protocol
|
117
|
+
xml.Port pool[:ports].find { |port| port[:type] == protocol.downcase.to_sym }[:port]
|
118
|
+
xml.HealthCheckPort
|
119
|
+
}
|
120
|
+
end
|
121
|
+
|
122
|
+
xml.ServicePort {
|
123
|
+
xml.Protocol "TCP"
|
124
|
+
xml.Port
|
125
|
+
xml.HealthCheckPort
|
126
|
+
}
|
127
|
+
|
128
|
+
}
|
129
|
+
end
|
130
|
+
xml.Operational "false"
|
131
|
+
}
|
132
|
+
end
|
133
|
+
|
134
|
+
LoadBalancer.instance.configurations.each do |configuration|
|
135
|
+
configuration[:virtual_servers].each do |virtual_server|
|
136
|
+
xml.VirtualServer {
|
137
|
+
xml.IsEnabled "true"
|
138
|
+
xml.Name virtual_server[:name]
|
139
|
+
xml.Interface('type' => "application/vnd.vmware.vcloud.orgVdcNetwork+xml", :name => virtual_server[:interface], :href => interfaces[virtual_server[:interface]])
|
140
|
+
xml.IpAddress virtual_server[:ip]
|
141
|
+
|
142
|
+
configuration[:pool][:ports].each do |port|
|
143
|
+
xml.ServiceProfile {
|
144
|
+
xml.IsEnabled port[:enabled]
|
145
|
+
xml.Protocol port[:type].to_s.upcase
|
146
|
+
xml.Port port[:port]
|
147
|
+
xml.Persistence {
|
148
|
+
if port[:type] == :https
|
149
|
+
xml.Method
|
150
|
+
else
|
151
|
+
xml.Method
|
152
|
+
end
|
153
|
+
}
|
154
|
+
}
|
155
|
+
end
|
156
|
+
|
157
|
+
xml.ServiceProfile {
|
158
|
+
xml.IsEnabled "false"
|
159
|
+
xml.Protocol "TCP"
|
160
|
+
xml.Port
|
161
|
+
xml.Persistence {
|
162
|
+
xml.Method
|
163
|
+
}
|
164
|
+
}
|
165
|
+
xml.Logging "false"
|
166
|
+
xml.Pool configuration[:pool][:name]
|
167
|
+
|
168
|
+
}
|
169
|
+
end
|
170
|
+
end
|
171
|
+
}
|
172
|
+
}
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def load_balancer (&block)
|
180
|
+
Component::LoadBalancer.instance.instance_eval(&block)
|
181
|
+
end
|