diff --git a/lib/fog/rackspace/load_balancer.rb b/lib/fog/rackspace/load_balancer.rb index 1a2db4ee6..57785d876 100644 --- a/lib/fog/rackspace/load_balancer.rb +++ b/lib/fog/rackspace/load_balancer.rb @@ -47,6 +47,8 @@ module Fog model :load_balancer collection :nodes model :node + collection :virtual_ips + model :virtual_ip request_path 'fog/rackspace/requests' request :create_load_balancer diff --git a/lib/fog/rackspace/models/load_balancer.rb b/lib/fog/rackspace/models/load_balancer.rb index 77e2d4ee9..181971324 100644 --- a/lib/fog/rackspace/models/load_balancer.rb +++ b/lib/fog/rackspace/models/load_balancer.rb @@ -17,18 +17,36 @@ module Fog attribute :updated attribute :name attribute :state, :aliases => 'status' + attribute :nodes + + def initialize(attributes) + #HACK - Since we are hacking how sub-collections work, we have to make sure the connection is valid first. + @connection = attributes[:connection] + super + end def nodes @nodes end - def nodes=(new_nodes) + def nodes=(new_nodes=[]) @nodes = Fog::Rackspace::LoadBalancer::Nodes.new({ :connection => connection, :load_balancer => self}) @nodes.load(new_nodes) end + def virtual_ips + @virtual_ips + end + + def virtual_ips=(new_virtual_ips=[]) + @virtual_ips = Fog::Rackspace::LoadBalancer::VirtualIps.new({ + :connection => connection, + :load_balancer => self}) + @virtual_ips.load(new_virtual_ips) + end + def destroy requires :identity connection.delete_load_balancer(identity) @@ -51,7 +69,7 @@ module Fog private def create requires :name, :protocol, :port, :virtual_ips, :nodes - data = connection.create_load_balancer(name, protocol, port, virtual_ips, nodes.to_object) + data = connection.create_load_balancer(name, protocol, port, virtual_ips.to_object, nodes.to_object) merge_attributes(data.body['loadBalancer']) end diff --git a/lib/fog/rackspace/models/nodes.rb b/lib/fog/rackspace/models/nodes.rb index 5a763ff1b..c7b54d358 100644 --- a/lib/fog/rackspace/models/nodes.rb +++ b/lib/fog/rackspace/models/nodes.rb @@ -22,12 +22,6 @@ module Fog nil end - def save - each do |node| - node.save - end - end - def to_object collect do |node| node.to_object diff --git a/lib/fog/rackspace/models/virtual_ip.rb b/lib/fog/rackspace/models/virtual_ip.rb new file mode 100644 index 000000000..7191cc263 --- /dev/null +++ b/lib/fog/rackspace/models/virtual_ip.rb @@ -0,0 +1,39 @@ +require 'fog/core/model' + +module Fog + module Rackspace + class LoadBalancer + class VirtualIp < Fog::Model + + identity :id + + attribute :address + attribute :type + attribute :ip_version, :aliases => 'ipVersion' + + def destroy + requires :identity, :load_balancer + connection.delete_virtual_ip(load_balancer.identity, identity) + true + end + + def save + raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if identity + requires :load_balancer, :type + data = connection.create_virtual_ip(load_balancer.id, type) + merge_attributes(data.body) + true + end + + def to_object + { :type => type } + end + + private + def load_balancer + collection.load_balancer + end + end + end + end +end diff --git a/lib/fog/rackspace/models/virtual_ips.rb b/lib/fog/rackspace/models/virtual_ips.rb new file mode 100644 index 000000000..40001fb6f --- /dev/null +++ b/lib/fog/rackspace/models/virtual_ips.rb @@ -0,0 +1,37 @@ +require 'fog/core/collection' +require 'fog/rackspace/models/virtual_ip' + +module Fog + module Rackspace + class LoadBalancer + class VirtualIps < Fog::Collection + model Fog::Rackspace::LoadBalancer::VirtualIp + + attr_accessor :load_balancer + + def all + data = all_raw + load(data) + end + + #HACK - This method is somewhat hacky since there isn't a way to retrieve a single virtual IP. Hopefully long term a method will + # be added that allows a single virtual IP to be returned + def get(virtual_ip_id) + data = all_raw.select { |virtual_ip| virtual_ip['id'] == virtual_ip_id }.first + data && new(data) + end + + def to_object + collect do |node| + node.to_object + end + end + + private + def all_raw + connection.list_virtual_ips(load_balancer.id).body['virtualIps'] + end + end + end + end +end diff --git a/tests/rackspace/models/nodes_tests.rb b/tests/rackspace/models/nodes_tests.rb index 0ca50be4e..afd3f0a1b 100644 --- a/tests/rackspace/models/nodes_tests.rb +++ b/tests/rackspace/models/nodes_tests.rb @@ -8,6 +8,7 @@ Shindo.tests('Fog::Rackspace::LoadBalancer | nodes', ['rackspace']) do :virtual_ips => [{ :type => 'PUBLIC'}], :nodes => [{ :address => '10.0.0.1', :port => 80, :condition => 'ENABLED'}] }) + #TODO - Add test to show that connection isn't passed to subcollections? @lb.wait_for { ready? } begin diff --git a/tests/rackspace/models/virtual_ip_tests.rb b/tests/rackspace/models/virtual_ip_tests.rb new file mode 100644 index 000000000..4f17c0873 --- /dev/null +++ b/tests/rackspace/models/virtual_ip_tests.rb @@ -0,0 +1,25 @@ +Shindo.tests('Fog::Rackspace::LoadBalancer | virtual_ip', ['rackspace']) do + + @service = Fog::Rackspace::LoadBalancer.new + @lb = @service.load_balancers.create({ + :name => ('fog' + Time.now.to_i.to_s), + :protocol => 'HTTP', + :port => 80, + :virtual_ips => [{ :type => 'PUBLIC'}], + :nodes => [{ :address => '10.0.0.1', :port => 80, :condition => 'ENABLED'}] + }) + @lb.wait_for { ready? } + + begin + model_tests(@lb.virtual_ips, { :type => 'PUBLIC'}, false) do + @lb.wait_for { ready? } + + tests("#save => existing virtual IP").raises(Fog::Errors::Error) do + @instance.save + end + end + ensure + @lb.wait_for { ready? } + @lb.destroy + end +end diff --git a/tests/rackspace/models/virtual_ips_tests.rb b/tests/rackspace/models/virtual_ips_tests.rb new file mode 100644 index 000000000..26b560598 --- /dev/null +++ b/tests/rackspace/models/virtual_ips_tests.rb @@ -0,0 +1,21 @@ +Shindo.tests('Fog::Rackspace::LoadBalancer | virtual_ips', ['rackspace']) do + + @service = Fog::Rackspace::LoadBalancer.new + @lb = @service.load_balancers.create({ + :name => ('fog' + Time.now.to_i.to_s), + :protocol => 'HTTP', + :port => 80, + :virtual_ips => [{ :type => 'PUBLIC'}], + :nodes => [{ :address => '10.0.0.1', :port => 80, :condition => 'ENABLED'}] + }) + @lb.wait_for { ready? } + + begin + collection_tests(@lb.virtual_ips, { :type => 'PUBLIC'}, false) do + @lb.wait_for { ready? } + end + ensure + @lb.wait_for { ready? } + @lb.destroy + end +end