vcloud-net-spinner 0.1.2

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 (47) hide show
  1. data/.gitignore +2 -0
  2. data/.travis.yml +7 -0
  3. data/CHANGELOG +12 -0
  4. data/Gemfile +4 -0
  5. data/README.md +109 -0
  6. data/Rakefile +25 -0
  7. data/bin/vcloud-net-spinner +5 -0
  8. data/docs/find_network_url.md +56 -0
  9. data/docs/find_organisation_edgegateway_uuid.md +58 -0
  10. data/jenkins.sh +6 -0
  11. data/lib/component/firewall.rb +83 -0
  12. data/lib/component/load_balancer.rb +182 -0
  13. data/lib/component/nat.rb +78 -0
  14. data/lib/vcloud_network_configurator.rb +64 -0
  15. data/lib/vcloud_network_configurator/configure_task.rb +22 -0
  16. data/lib/vcloud_network_configurator/edge_gateway.rb +51 -0
  17. data/lib/vcloud_network_configurator/vcloud_auth_request.rb +39 -0
  18. data/lib/vcloud_network_configurator/vcloud_check_for_configure_task_request.rb +26 -0
  19. data/lib/vcloud_network_configurator/vcloud_configure_request.rb +58 -0
  20. data/lib/vcloud_network_configurator/vcloud_settings.rb +22 -0
  21. data/lib/vcloud_network_configurator/version.rb +1 -0
  22. data/spec/component/firewall.xml +45 -0
  23. data/spec/component/firewall_spec.rb +120 -0
  24. data/spec/component/lb.xml +567 -0
  25. data/spec/component/load_balancer_spec.rb +73 -0
  26. data/spec/component/nat.xml +146 -0
  27. data/spec/component/nat_spec.rb +35 -0
  28. data/spec/integration/authorization_failed_spec.rb +26 -0
  29. data/spec/integration/happy_path_firewall_spec.rb +74 -0
  30. data/spec/integration/happy_path_loadbalancer_spec.rb +173 -0
  31. data/spec/integration/happy_path_nat_spec.rb +78 -0
  32. data/spec/integration/test_data/happy_path_auth_response.xml +30 -0
  33. data/spec/integration/test_data/rules_dir/common_firewall.rb +6 -0
  34. data/spec/integration/test_data/rules_dir/common_lb.rb +10 -0
  35. data/spec/integration/test_data/rules_dir/common_nat.rb +0 -0
  36. data/spec/integration/test_data/rules_dir/preview/firewall.rb +0 -0
  37. data/spec/integration/test_data/rules_dir/preview/interfaces.yaml +2 -0
  38. data/spec/integration/test_data/rules_dir/preview/lb.rb +0 -0
  39. data/spec/integration/test_data/rules_dir/preview/nat.rb +4 -0
  40. data/spec/spec_helper.rb +9 -0
  41. data/spec/vcloud_network_configurator/configure_task_spec.rb +59 -0
  42. data/spec/vcloud_network_configurator/edge_gateway_spec.rb +41 -0
  43. data/spec/vcloud_network_configurator/vcloud_auth_request_spec.rb +20 -0
  44. data/spec/vcloud_network_configurator/vcloud_configure_request_spec.rb +22 -0
  45. data/spec/vcloud_network_configurator/vcloud_settings_spec.rb +19 -0
  46. data/vcloud-net-spinner.gemspec +33 -0
  47. metadata +215 -0
@@ -0,0 +1,2 @@
1
+ .bundle/
2
+ Gemfile.lock
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ before_script: bundle install
5
+ script:
6
+ - bundle exec rake spec
7
+ - bundle exec rake integration
@@ -0,0 +1,12 @@
1
+ 0.1.2 2013-08-13
2
+
3
+ - Exit when no rules provided
4
+ - Made the presence of files in directory tree as optional
5
+
6
+ 0.1.1 2013-08-13
7
+
8
+ - Renaming the gem to vcloud-net-spinner
9
+
10
+ 0.1.0 2013-08-07
11
+
12
+ - Introucing vcloud-network-configurator
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in gds-provisioning.gemspec
4
+ gemspec
@@ -0,0 +1,109 @@
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-net-spinner
10
+
11
+ ## Usage
12
+
13
+ Usage: vcloud-net-spinner [options] API_URL
14
+ -u, --username=U Vcloud Username
15
+ -p, --password=P Vcloud Password
16
+ -e, --env=E Environment: preview | staging | production
17
+ -U, --organization-edgegateway-uuid=U UID: This is required to configure edgegateway services. For more info refer to
18
+ docs/find_organisation_edgegateway_uuid
19
+ -c, --component=c Environment: lb|firewall|nat
20
+ -o, --organization=o Organization: optional. Will default to environment
21
+ -d, --rule-directory=d Rules Directory: From where to read the NAT/Firewal/LB rules
22
+
23
+ Note: organization maps to the organization name in vcloud. Whereas,
24
+ environment maps to your internal environment reference (e.g.
25
+ preview, qa, staging, production, etc)
26
+
27
+ ### Example
28
+
29
+ vcloud-net-spinner -u username -p password -e preview -U 1yenz127ynz1872eyz12yz817e -c firewall -o development -d . http://vcloud.vendor.com/api
30
+
31
+ ### Rules Directory
32
+
33
+ A particular rules directory structure could be as follows.
34
+
35
+ .
36
+ ├── Gemfile
37
+ ├── Gemfile.lock
38
+ ├── common_firewall.rb
39
+ ├── common_lb.rb
40
+ ├── common_nat.rb
41
+ ├── env1
42
+ │ ├── firewall.rb
43
+ │ ├── interfaces.yaml
44
+ │ ├── lb.rb
45
+ │ └── nat.rb
46
+ ├── env2
47
+ ├── firewall.rb
48
+ ├── interfaces.yaml
49
+ ├── lb.rb
50
+ └── nat.rb
51
+
52
+ * Here each environment represent a separate organisation with your vcloud
53
+ vendor (eg qa, staging, production). These could have specific rules for nat,
54
+ firewall. Also these can have common firewall rules which could be shared
55
+ across all environments. A common example of such a situation is internal
56
+ network firewall rules are usually shared across environments, whereas
57
+ external network firewall rules would be different for all environment.
58
+
59
+ * Specific network rules => `env1/firewall.rb`, `env1/nat.rb`, `env1/lb.rb`
60
+ * Common network rules => `./common_firewall.rb`, `./common_lb.rb`, `./common_lb.rb`
61
+
62
+ * interfaces.yaml file:
63
+ To find the urls for network, follow the document at
64
+ `docs/find_network_url`
65
+
66
+ interfaces:
67
+ Network-1: "https://localhost:4567/api/admin/network/<vdc-network-uuid>"
68
+ Network-2: "https://localhost:4567/api/admin/network/<vdc-network-uuid>"
69
+
70
+ ### DSL
71
+
72
+ #### Firewall
73
+
74
+ firewall do
75
+ rule "<description>" do
76
+ source :ip => "172.10.0.0/8"
77
+ destination :ip => "172.10.0.5", :port => 4567
78
+ end
79
+ end
80
+
81
+ #### NAT
82
+
83
+ nat do
84
+ snat :interface => "<key-from-interfaces.rb>", :original => { :ip => "internal-ip" }, :translated => { :ip => "external-ip" }, :desc => "description"
85
+ dnat :interface => "<key-from-interfaces.rb>", :original => { :ip => "external-ip", :port => 22 }, :translated => { :ip => "internal-ip", :port => 22 }, :desc => "SSH"
86
+ end
87
+
88
+
89
+ #### Load Balancer
90
+
91
+ load_balancer do
92
+ configure "description-1" do
93
+ pool ["<ip-1>", "<ip-2>"] do
94
+ http
95
+ https
96
+ end
97
+
98
+ virtual_server :name => "description-1", :interface => "<key-from-interfaces.rb>", :ip => "<vse-ip>"
99
+ end
100
+
101
+ configure "description-2" do
102
+ pool ["<ip-1>", "<ip-2>", "<ip-3>"] do
103
+ http :port => 8080, :health_check_path => "</router/healthcheck>"
104
+ https
105
+ end
106
+
107
+ virtual_server :name => "description-2", :interface => "<key-from-interfaces.rb>", :ip => "<vse-ip>"
108
+ end
109
+ end
@@ -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-net-spinner.gemspec", :rubygems)
23
+ puts "Published #{gem}" if gem
24
+ end
25
+
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.dirname(__FILE__) + '/../lib'
3
+ require 'vcloud_network_configurator'
4
+
5
+ VcloudNetworkConfigurator.new(ARGV).execute
@@ -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
+
@@ -0,0 +1,6 @@
1
+ #!/bin/bash -x
2
+ set -e
3
+ bundle install --path "${HOME}/bundles/${JOB_NAME}"
4
+ bundle exec rake spec
5
+ bundle exec rake integration
6
+ bundle exec rake publish_gem --trace
@@ -0,0 +1,83 @@
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
+ return if Firewall.instance.rules.nil? or Firewall.instance.rules.empty?
40
+ Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
41
+ 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") {
42
+ xml.FirewallService {
43
+ xml.IsEnabled "true"
44
+ xml.DefaultAction "drop"
45
+ xml.LogDefaultAction "false"
46
+
47
+ Firewall.instance.rules.each do |rule|
48
+ xml.FirewallRule {
49
+ xml.Id rule[:id]
50
+ xml.IsEnabled rule[:enabled]
51
+ xml.MatchOnTranslate "false"
52
+ xml.Description rule[:description]
53
+ xml.Policy "allow"
54
+
55
+ xml.Protocols {
56
+ rule[:protocols].each do |protocol|
57
+ xml.send(protocol.to_s.capitalize, true)
58
+ end
59
+ }
60
+
61
+ if rule[:protocols].first == :icmp
62
+ xml.IcmpSubType "any"
63
+ end
64
+
65
+ xml.Port rule[:destination][:port] == "Any" ? "-1" : rule[:destination][:port]
66
+ xml.DestinationPortRange rule[:destination][:port]
67
+ xml.DestinationIp rule[:destination][:ip]
68
+ xml.SourcePort rule[:source][:port] == "Any" ? "-1" : rule[:source][:port]
69
+ xml.SourcePortRange rule[:source][:port]
70
+ xml.SourceIp rule[:source][:ip]
71
+ xml.EnableLogging "false"
72
+ }
73
+ end
74
+ }
75
+ }
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ def firewall (&block)
82
+ Component::Firewall.instance.instance_eval(&block)
83
+ end
@@ -0,0 +1,182 @@
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
+ return if LoadBalancer.instance.pools.nil? or LoadBalancer.instance.pools.empty?
63
+ Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
64
+ 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") {
65
+ xml.LoadBalancerService {
66
+ xml.IsEnabled 'false'
67
+ LoadBalancer.instance.pools.each do |pool|
68
+ xml.Pool {
69
+ xml.Name pool[:name]
70
+
71
+ pool[:ports].each do |port|
72
+ xml.ServicePort {
73
+ xml.IsEnabled port[:enabled]
74
+ xml.Protocol port[:port] == 443 ? "HTTPS" : "HTTP"
75
+ xml.Algorithm 'ROUND_ROBIN'
76
+ xml.Port port[:port]
77
+
78
+ if port[:health_check_port]
79
+ xml.HealthCheckPort port[:health_check_port]
80
+ else
81
+ xml.HealthCheckPort
82
+ end
83
+
84
+ xml.HealthCheck {
85
+ xml.Mode port[:health_check_mode]
86
+ xml.Uri port[:health_check_path]
87
+ xml.HealthThreshold "2"
88
+ xml.UnhealthThreshold "3"
89
+ xml.Interval "5"
90
+ xml.Timeout "15"
91
+ }
92
+ }
93
+ end
94
+
95
+ xml.ServicePort {
96
+ xml.IsEnabled 'false'
97
+ xml.Protocol "TCP"
98
+ xml.Algorithm 'ROUND_ROBIN'
99
+ xml.Port
100
+ xml.HealthCheckPort
101
+ xml.HealthCheck {
102
+ xml.Mode "TCP"
103
+ xml.HealthThreshold "2"
104
+ xml.UnhealthThreshold "3"
105
+ xml.Interval "5"
106
+ xml.Timeout "15"
107
+ }
108
+ }
109
+
110
+ pool[:nodes].each do |node|
111
+ xml.Member {
112
+ xml.IpAddress node
113
+ xml.Weight "1"
114
+
115
+ ["HTTP", "HTTPS"].each do |protocol|
116
+ xml.ServicePort {
117
+ xml.Protocol protocol
118
+ xml.Port pool[:ports].find { |port| port[:type] == protocol.downcase.to_sym }[:port]
119
+ xml.HealthCheckPort
120
+ }
121
+ end
122
+
123
+ xml.ServicePort {
124
+ xml.Protocol "TCP"
125
+ xml.Port
126
+ xml.HealthCheckPort
127
+ }
128
+
129
+ }
130
+ end
131
+ xml.Operational "false"
132
+ }
133
+ end
134
+
135
+ LoadBalancer.instance.configurations.each do |configuration|
136
+ configuration[:virtual_servers].each do |virtual_server|
137
+ xml.VirtualServer {
138
+ xml.IsEnabled "true"
139
+ xml.Name virtual_server[:name]
140
+ xml.Interface('type' => "application/vnd.vmware.vcloud.orgVdcNetwork+xml", :name => virtual_server[:interface], :href => interfaces[virtual_server[:interface]])
141
+ xml.IpAddress virtual_server[:ip]
142
+
143
+ configuration[:pool][:ports].each do |port|
144
+ xml.ServiceProfile {
145
+ xml.IsEnabled port[:enabled]
146
+ xml.Protocol port[:type].to_s.upcase
147
+ xml.Port port[:port]
148
+ xml.Persistence {
149
+ if port[:type] == :https
150
+ xml.Method
151
+ else
152
+ xml.Method
153
+ end
154
+ }
155
+ }
156
+ end
157
+
158
+ xml.ServiceProfile {
159
+ xml.IsEnabled "false"
160
+ xml.Protocol "TCP"
161
+ xml.Port
162
+ xml.Persistence {
163
+ xml.Method
164
+ }
165
+ }
166
+ xml.Logging "false"
167
+ xml.Pool configuration[:pool][:name]
168
+
169
+ }
170
+ end
171
+ end
172
+ }
173
+ }
174
+ end
175
+ end
176
+
177
+ end
178
+ end
179
+
180
+ def load_balancer (&block)
181
+ Component::LoadBalancer.instance.instance_eval(&block)
182
+ end