diff --git a/lib/fog/collection.rb b/lib/fog/collection.rb index 39c9d8950..8c22af18f 100644 --- a/lib/fog/collection.rb +++ b/lib/fog/collection.rb @@ -35,10 +35,14 @@ module Fog end end - def self.model(new_model) - @model = new_model + def self.model(new_model=nil) + if new_model == nil + @model + else + @model = new_model + end end - + def self.aliases @aliases ||= {} end diff --git a/lib/fog/vcloud.rb b/lib/fog/vcloud.rb index ef5174ba9..17606465e 100644 --- a/lib/fog/vcloud.rb +++ b/lib/fog/vcloud.rb @@ -39,7 +39,7 @@ module Fog end org_list = @login_results.body.organizations if organization = @login_results.body.organizations.first - URI.parse(organization[:href]) + organization[:href] else nil end @@ -132,6 +132,23 @@ module Fog :versions => [ { :version => "v0.8", :login_url => "https://fakey.com/api/v0.8/login", :supported => true } ], + :vdc_resources => [ + { + :type => "application/vnd.vmware.vcloud.vApp+xml", + :href => "https://fakey.com/api/v0.8/vapp/61", + :name => "Foo App 1" + }, + { + :type => "application/vnd.vmware.vcloud.vApp+xml", + :href => "https://fakey.com/api/v0.8/vapp/62", + :name => "Bar App 1" + }, + { + :type => "application/vnd.vmware.vcloud.vApp+xml", + :href => "https://fakey.com/api/v0.8/vapp/63", + :name => "Bar App 2" + } + ], :organizations => [ { @@ -250,7 +267,11 @@ module Fog class < link.href, :name => link.name } } + load(data) + end + EOS + end + end + + def vcloud_type(vcloud_type=nil) + unless vcloud_type + @vcloud_type + else + @vcloud_type = vcloud_type + end + end + + def get_request(get_request=nil) + unless get_request + @get_request + else + @get_request = get_request + class_eval <<-EOS, __FILE__, __LINE__ + def get(uri) + item = new(:href => uri) + item.reload + end + def get_raw(uri) + connection.#{@get_request}(uri) + end + EOS + end + end + end + + def [](index) + self.slice(index).reload + end + + def reload + self.all + end + + end + end +end diff --git a/lib/fog/vcloud/model.rb b/lib/fog/vcloud/model.rb new file mode 100644 index 000000000..a344a04aa --- /dev/null +++ b/lib/fog/vcloud/model.rb @@ -0,0 +1,49 @@ +module Fog + module Vcloud + class Model < Fog::Model + + #def self.attribute(name, other_names = []) + # super + # class_eval <<-EOS, __FILE__, __LINE__ + # def #{name}=(new_#{name}) + # @#{name} = new_#{name} + # end + # EOS + #end + + def self.inherited(klass) + attributes.each { |attribute| klass.attribute attribute } + klass.instance_variable_set(:@identity, @identity) + klass.instance_variable_set(:@aliases, @aliases) + end + + def self.delete_attribute(name) + if @attributes.reject! { |item| item == name } + class_eval <<-EOS,__FILE__,__LINE__ + undef_method :#{name} + undef_method :#{name}= + EOS + aliases.reject! { |key, value| value == name || key == name } + end + end + + def reload + if data = collection.get_raw(identity) + merge_get_raw_result(data) + self + end + end + + def merge_get_raw_result(data) + data.body.each_pair do |key,value| + if aliased_key = self.class.aliases[key] + send("#{aliased_key}=", value) + else + send("#{key}=", value) + end + end + end + + end + end +end diff --git a/lib/fog/vcloud/models/vdc.rb b/lib/fog/vcloud/models/vdc.rb new file mode 100644 index 000000000..572603ca4 --- /dev/null +++ b/lib/fog/vcloud/models/vdc.rb @@ -0,0 +1,36 @@ +require 'fog/model' + +module Fog + module Vcloud + class Vdc < Fog::Vcloud::Model + + identity :href + + attribute :name + attribute :other_links, :links + attribute :resource_entity_links, :resource_entities + attribute :network_links, :networks + attribute :cpu_capacity + attribute :storage_capacity + attribute :memory_capacity + attribute :vm_quota + attribute :enabled + attribute :nic_quota + attribute :network_quota + attribute :vcloud_type, :type + attribute :xmlns + attribute :description + attribute :allocation_model + + #def networks + # connection.networks(:vdc_uri => @uri) + #end + + #def addresses + # connection.addresses(:vdc_uri => @uri) + #end + + end + + end +end diff --git a/lib/fog/vcloud/models/vdcs.rb b/lib/fog/vcloud/models/vdcs.rb new file mode 100644 index 000000000..b40ebf454 --- /dev/null +++ b/lib/fog/vcloud/models/vdcs.rb @@ -0,0 +1,36 @@ +module Fog + module Vcloud + class Mock + def vdcs(options = {}) + @vdcs ||= Fog::Vcloud::Vdcs.new(options.merge(:connection => self)) + end + end + + class Real + def vdcs(options = {}) + @vdcs ||= Fog::Vcloud::Vdcs.new(options.merge(:connection => self)) + end + end + + class Vdcs < Fog::Vcloud::Collection + + model Fog::Vcloud::Vdc + + get_request :get_vdc + vcloud_type "application/vnd.vmware.vcloud.vdc+xml" + all_request lambda { |vdcs| vdcs.connection.get_organization(vdcs.organization_uri) } + + def organization_uri + @organizatio_uri ||= connection.default_organization_uri + end + + private + + def organization_uri=(new_organization_uri) + @organization_uri = new_organization_uri + end + + end + + end +end diff --git a/lib/fog/vcloud/parser.rb b/lib/fog/vcloud/parser.rb index cba38c8a9..dc71947c3 100644 --- a/lib/fog/vcloud/parser.rb +++ b/lib/fog/vcloud/parser.rb @@ -10,6 +10,9 @@ module Fog until attributes.empty? link[attributes.shift.downcase] = attributes.shift end + if link.href + link.href = URI.parse(link.href) + end link end @@ -23,7 +26,7 @@ module Fog root[attributes.shift.downcase] = attributes.shift end end - @response.href = root['href'] + @response.href = URI.parse(root['href']) @response.name = root['name'] @response.type = root['type'] @response.xmlns = root['xmlns'] diff --git a/lib/fog/vcloud/parsers/get_vdc.rb b/lib/fog/vcloud/parsers/get_vdc.rb index f19a98324..d9803bd47 100644 --- a/lib/fog/vcloud/parsers/get_vdc.rb +++ b/lib/fog/vcloud/parsers/get_vdc.rb @@ -8,14 +8,31 @@ module Fog #vCloud API Guide v0.9 - Page 27 def reset - @response = Struct::VcloudVdc.new([]) + @target = nil + @response = Struct::VcloudVdc.new([],[],[],Struct::VcloudXCapacity.new,Struct::VcloudXCapacity.new,Struct::VcloudXCapacity.new) end def start_element(name, attributes) @value = '' case name + when 'Cpu' + @target = :cpu_capacity + when 'Memory' + @target = :memory_capacity + when 'StorageCapacity' + @target = :storage_capacity + when 'NetworkQuota' + @target = :network_quota + when 'VmQuota' + @target = :vm_quota + when 'NicQuota' + @target = :nic_quota when 'Link' @response.links << generate_link(attributes) + when 'ResourceEntity' + @response.resource_entities << generate_link(attributes) + when 'Network' + @response.networks << generate_link(attributes) when 'Vdc' handle_root(attributes) end @@ -23,10 +40,18 @@ module Fog def end_element(name) case name + when 'Allocated', 'Limit', 'Used' + @response[@target][name.downcase] = @value.to_i + when 'Units' + @response[@target][name.downcase] = @value when "AllocationModel" @response.allocation_model = @value when "Description" @response.description = @value + when "NicQuota", "VmQuota", "NetworkQuota" + @response[@target] = @value.to_i + when 'IsEnabled' + @response.enabled = (@value == 'true' ? true : false) end end diff --git a/lib/fog/vcloud/parsers/login.rb b/lib/fog/vcloud/parsers/login.rb index 6c6254907..7f12ca6cd 100644 --- a/lib/fog/vcloud/parsers/login.rb +++ b/lib/fog/vcloud/parsers/login.rb @@ -2,7 +2,7 @@ module Fog module Parsers module Vcloud - class Login < Fog::Parsers::Base + class Login < Fog::Parsers::Vcloud::Base # # Based off of: # http://support.theenterprisecloud.com/kb/default.asp?id=536&Lang=1&SID= @@ -26,11 +26,7 @@ module Fog end end when 'Org' - organization = Struct::VcloudOrgLink.new - until attributes.empty? - organization[attributes.shift.downcase.to_sym] = attributes.shift - end - @response.organizations << organization + @response.organizations << generate_link(attributes) end end diff --git a/lib/fog/vcloud/requests/get_organization.rb b/lib/fog/vcloud/requests/get_organization.rb index 984401a06..edce0363e 100644 --- a/lib/fog/vcloud/requests/get_organization.rb +++ b/lib/fog/vcloud/requests/get_organization.rb @@ -23,7 +23,7 @@ module Fog # # vCloud API Guide v0.9 - Page 26 # - if org = DATA[:organizations].detect { |org| org[:info][:href] == organization_uri.to_s } + if org = mock_data[:organizations].detect { |org| URI.parse(org[:info][:href]) == organization_uri } xml = Builder::XmlMarkup.new mock_it Fog::Parsers::Vcloud::GetOrganization.new, 200, diff --git a/lib/fog/vcloud/requests/get_vdc.rb b/lib/fog/vcloud/requests/get_vdc.rb index 72e0c73a3..3d554e295 100644 --- a/lib/fog/vcloud/requests/get_vdc.rb +++ b/lib/fog/vcloud/requests/get_vdc.rb @@ -20,7 +20,7 @@ module Fog #vCloud API Guide v0.9 - Page 27 def get_vdc(vdc_uri) - if vdc = DATA[:organizations].map { |org| org[:vdcs] }.flatten.detect { |vdc| vdc[:href] == vdc_uri } + if vdc = DATA[:organizations].map { |org| org[:vdcs] }.flatten.detect { |vdc| URI.parse(vdc[:href]) == vdc_uri } xml = Builder::XmlMarkup.new mock_it Fog::Parsers::Vcloud::GetVdc.new, 200, xml.Vdc(xmlns.merge(:href => vdc[:href], :name => vdc[:name])) { @@ -47,6 +47,37 @@ module Fog :href => vdc[:href] + "/action/composeVApp") xml.AllocationModel("AllocationPool") xml.Description(vdc[:name] + " VDC") + xml.ResourceEntities { + DATA[:vdc_resources].each do |resource| + xml.ResourceEntity(resource) + end + } + xml.AvailableNetworks { + vdc[:networks].each do |network| + xml.Network( :name => network[:name], :href => network[:href], :type => "application/vnd.vmware.vcloud.network+xml" ) + end + } + xml.ComputeCapacity{ + xml.Cpu { + xml.Units("Mhz") + xml.Allocated(vdc[:cpu][:allocated]) + xml.Limit(vdc[:cpu][:allocated]) + } + xml.Memory { + xml.Units("MB") + xml.Allocated(vdc[:memory][:allocated]) + xml.Limit(vdc[:memory][:allocated]) + } + } + xml.StorageCapacity{ + xml.Units("MB") + xml.Allocated(vdc[:storage][:allocated]) + xml.Limit(vdc[:storage][:allocated]) + } + xml.VmQuota(0) + xml.NicQuota(0) + xml.IsEnabled('true') + xml.NetworkQuota(0) #FIXME: Incomplete }, { 'Content-Type' => 'application/vnd.vmware.vcloud.vdc+xml' } else diff --git a/lib/fog/vcloud/terremark/ecloud.rb b/lib/fog/vcloud/terremark/ecloud.rb index b7d497a65..9d85fcc6a 100644 --- a/lib/fog/vcloud/terremark/ecloud.rb +++ b/lib/fog/vcloud/terremark/ecloud.rb @@ -11,13 +11,14 @@ module Fog #Do anything we need to do here that's specific to ecloud unless @required require 'fog/vcloud/terremark/all' + require 'fog/vcloud/terremark/ecloud/models/vdc' + require 'fog/vcloud/terremark/ecloud/models/vdcs' require 'fog/vcloud/terremark/ecloud/parsers/get_vdc' require 'fog/vcloud/terremark/ecloud/requests/login' require 'fog/vcloud/terremark/ecloud/requests/get_vdc' Struct.new("TmrkEcloudVdc", :links, :resource_entities, :networks, :cpu_capacity, :storage_capacity, :memory_capacity, :deployed_vm_quota, :instantiated_vm_quota, :href, :type, :name, :xmlns, :description) - Struct.new("TmrkEcloudXCapacity", :units, :allocated, :used, :limit) @required = true end if Fog.mocking? diff --git a/lib/fog/vcloud/terremark/ecloud/models/vdc.rb b/lib/fog/vcloud/terremark/ecloud/models/vdc.rb new file mode 100644 index 000000000..9fbf9eb6e --- /dev/null +++ b/lib/fog/vcloud/terremark/ecloud/models/vdc.rb @@ -0,0 +1,20 @@ +module Fog + module Vcloud + module Terremark + module Ecloud + class Vdc < Fog::Vcloud::Vdc + + delete_attribute :enabled + delete_attribute :vm_quota + delete_attribute :nic_quota + delete_attribute :network_quota + delete_attribute :allocation_model + + attribute :deployed_vm_quota + attribute :instantiated_vm_quota + + end + end + end + end +end diff --git a/lib/fog/vcloud/terremark/ecloud/models/vdcs.rb b/lib/fog/vcloud/terremark/ecloud/models/vdcs.rb new file mode 100644 index 000000000..70fdfd801 --- /dev/null +++ b/lib/fog/vcloud/terremark/ecloud/models/vdcs.rb @@ -0,0 +1,29 @@ +module Fog + module Vcloud + module Terremark + module Ecloud + module Mock + def vdcs(options = {}) + @vdcs ||= Fog::Vcloud::Terremark::Ecloud::Vdcs.new(options.merge(:connection => self)) + end + end + + module Real + def vdcs(options = {}) + @vdcs ||= Fog::Vcloud::Terremark::Ecloud::Vdcs.new(options.merge(:connection => self)) + end + end + + class Vdcs < Fog::Vcloud::Vdcs + + model Fog::Vcloud::Terremark::Ecloud::Vdc + + #get_request :get_vdc + #vcloud_type "application/vnd.vmware.vcloud.vdc+xml" + #all_request lambda { |vdcs| vdcs.connection.get_organization(vdcs.organization_uri) } + + end + end + end + end +end diff --git a/lib/fog/vcloud/terremark/ecloud/parsers/get_vdc.rb b/lib/fog/vcloud/terremark/ecloud/parsers/get_vdc.rb index 80c694f1b..ae27a177b 100644 --- a/lib/fog/vcloud/terremark/ecloud/parsers/get_vdc.rb +++ b/lib/fog/vcloud/terremark/ecloud/parsers/get_vdc.rb @@ -8,9 +8,9 @@ module Fog def reset @target = nil - @response = Struct::TmrkEcloudVdc.new([],[],[],Struct::TmrkEcloudXCapacity.new,Struct::TmrkEcloudXCapacity.new, - Struct::TmrkEcloudXCapacity.new,Struct::TmrkEcloudXCapacity.new, - Struct::TmrkEcloudXCapacity.new) + @response = Struct::TmrkEcloudVdc.new([],[],[],Struct::VcloudXCapacity.new,Struct::VcloudXCapacity.new, + Struct::VcloudXCapacity.new,Struct::VcloudXCapacity.new, + Struct::VcloudXCapacity.new) end def start_element(name, attributes) diff --git a/lib/fog/vcloud/terremark/ecloud/requests/get_vdc.rb b/lib/fog/vcloud/terremark/ecloud/requests/get_vdc.rb index f14e1688e..ebb658121 100644 --- a/lib/fog/vcloud/terremark/ecloud/requests/get_vdc.rb +++ b/lib/fog/vcloud/terremark/ecloud/requests/get_vdc.rb @@ -22,7 +22,7 @@ module Fog #http://support.theenterprisecloud.com/kb/default.asp?id=545&Lang=1&SID= def get_vdc(vdc_uri) - if vdc = mock_data[:organizations].map { |org| org[:vdcs] }.flatten.detect { |vdc| vdc[:href] == vdc_uri } + if vdc = mock_data[:organizations].map { |org| org[:vdcs] }.flatten.detect { |vdc| URI.parse(vdc[:href]) == vdc_uri } xml = Builder::XmlMarkup.new mock_it Fog::Parsers::Vcloud::Terremark::Ecloud::GetVdc.new, 200, xml.Vdc(xmlns.merge(:href => vdc[:href], :name => vdc[:name])) { diff --git a/lib/fog/vcloud/terremark/vcloud/requests/get_vdc.rb b/lib/fog/vcloud/terremark/vcloud/requests/get_vdc.rb index 383f6c427..ef44009c0 100644 --- a/lib/fog/vcloud/terremark/vcloud/requests/get_vdc.rb +++ b/lib/fog/vcloud/terremark/vcloud/requests/get_vdc.rb @@ -22,7 +22,7 @@ module Fog #https://community.vcloudexpress.terremark.com/en-us/product_docs/w/wiki/09-get-vdc.aspx def get_vdc(vdc_uri) - if vdc = mock_data[:organizations].map { |org| org[:vdcs] }.flatten.detect { |vdc| vdc[:href] == vdc_uri } + if vdc = mock_data[:organizations].map { |org| org[:vdcs] }.flatten.detect { |vdc| URI.parse(vdc[:href]) == vdc_uri } xml = Builder::XmlMarkup.new mock_it Fog::Parsers::Vcloud::Terremark::Vcloud::GetVdc.new, 200, xml.Vdc(xmlns.merge(:href => vdc[:href], :name => vdc[:name])) { diff --git a/spec/vcloud/models/vdc_spec.rb b/spec/vcloud/models/vdc_spec.rb new file mode 100644 index 000000000..5ce40dacc --- /dev/null +++ b/spec/vcloud/models/vdc_spec.rb @@ -0,0 +1,46 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe "Fog::Vcloud::Vdc", :type => :vcloud_model do + + describe :class do + subject { Fog::Vcloud::Vdc } + + it { should have_identity :href } + + it { should have_only_these_attributes [:allocation_model, :cpu_capacity, :description, :enabled, :href, :memory_capacity, :name, :network_links, :network_quota, + :nic_quota, :other_links, :resource_entity_links, :storage_capacity, :vcloud_type, :vm_quota, :xmlns] } + end + + context "with no uri" do + + subject { Fog::Vcloud::Vdc.new() } + + its(:href) { should be_nil } + its(:identity) { should be_nil } + end + + context "as a collection member" do + subject { @vcloud.vdcs[0] } + + its(:href) { should == URI.parse(@mock_vdc[:href]) } + its(:identity) { should == URI.parse(@mock_vdc[:href]) } + its(:name) { should == @mock_vdc[:name] } + its(:other_links) { should have(7).items } + its(:resource_entity_links) { should have(3).items } + its(:network_links) { should have(2).items } + + its(:cpu_capacity) { should == Struct::VcloudXCapacity.new('Mhz',@mock_vdc[:cpu][:allocated], nil, @mock_vdc[:cpu][:allocated]) } + its(:memory_capacity) { should == Struct::VcloudXCapacity.new('MB',@mock_vdc[:memory][:allocated], nil, @mock_vdc[:memory][:allocated]) } + its(:storage_capacity) { should == Struct::VcloudXCapacity.new('MB',@mock_vdc[:storage][:allocated], nil, @mock_vdc[:storage][:allocated]) } + + its(:vm_quota) { should == 0 } + its(:nic_quota) { should == 0 } + its(:network_quota) { should == 0 } + + its(:enabled) { should == true } + + end + + + +end diff --git a/spec/vcloud/models/vdcs_spec.rb b/spec/vcloud/models/vdcs_spec.rb new file mode 100644 index 000000000..f8ec36959 --- /dev/null +++ b/spec/vcloud/models/vdcs_spec.rb @@ -0,0 +1 @@ +require 'spec_helper' diff --git a/spec/vcloud/requests/get_organization_spec.rb b/spec/vcloud/requests/get_organization_spec.rb index a9c1dd0ef..6b7795e5c 100644 --- a/spec/vcloud/requests/get_organization_spec.rb +++ b/spec/vcloud/requests/get_organization_spec.rb @@ -27,12 +27,12 @@ describe Fog::Vcloud, :type => :vcloud_request do its(:links) { should have(@mock_organization[:vdcs].length * 3).links } its(:name) { should == @mock_organization[:info][:name] } - its(:href) { should == @mock_organization[:info][:href] } + its(:href) { should == URI.parse(@mock_organization[:info][:href]) } let(:link) { subject.links[0] } specify { link.should be_an_instance_of Struct::VcloudLink } specify { link.rel.should == "down" } - specify { link.href.should == @mock_vdc[:href] } + specify { link.href.should == URI.parse(@mock_vdc[:href]) } specify { link.type.should == "application/vnd.vmware.vcloud.vdc+xml" } specify { link.name.should == @mock_vdc[:name] } end diff --git a/spec/vcloud/requests/get_vdc_spec.rb b/spec/vcloud/requests/get_vdc_spec.rb index 6769316d2..a14c9596d 100644 --- a/spec/vcloud/requests/get_vdc_spec.rb +++ b/spec/vcloud/requests/get_vdc_spec.rb @@ -11,7 +11,7 @@ describe Fog::Vcloud, :type => :vcloud_request do describe :get_vdc, :type => :vcloud_request do context "with a valid vdc uri" do - before { @vdc = @vcloud.get_vdc(@mock_vdc[:href]) } + before { @vdc = @vcloud.get_vdc(URI.parse(@mock_vdc[:href])) } subject { @vdc } it_should_behave_like "all requests" @@ -30,13 +30,16 @@ describe Fog::Vcloud, :type => :vcloud_request do it_should_behave_like "it has a vcloud v0.8 xmlns" its(:links) { should have(7).links } + its(:resource_entities) { should have(3).links } + its(:networks) { should have(2).networks } + its(:name) { should == @mock_vdc[:name] } - its(:href) { should == @mock_vdc[:href] } + its(:href) { should == URI.parse(@mock_vdc[:href]) } let(:link) { subject.links[0] } specify { link.should be_an_instance_of Struct::VcloudLink } specify { link.rel.should == "up" } - specify { link.href.should == @mock_organization[:info][:href] } + specify { link.href.should == URI.parse(@mock_organization[:info][:href]) } specify { link.type.should == "application/vnd.vmware.vcloud.org+xml" } end end diff --git a/spec/vcloud/spec_helper.rb b/spec/vcloud/spec_helper.rb index d252ff487..28b590b9b 100644 --- a/spec/vcloud/spec_helper.rb +++ b/spec/vcloud/spec_helper.rb @@ -80,9 +80,9 @@ shared_examples_for "all login requests" do before { @org = @orglist.organizations.first } subject { @org } - it { should be_an_instance_of Struct::VcloudOrgLink } + it { should be_an_instance_of Struct::VcloudLink } - its(:href) { should == @mock_organization[:info][:href] } + its(:href) { should == URI.parse(@mock_organization[:info][:href]) } its(:name) { should == @mock_organization[:info][:name] } its(:type) { should == "application/vnd.vmware.vcloud.org+xml" } @@ -102,7 +102,7 @@ end shared_examples_for "a vdc catalog link" do it_should_behave_like "all rel=down vcloud links" it_should_behave_like "all vcloud catalog links" - its(:href) { should == @mock_vdc[:href] + "/catalog" } + its(:href) { should == URI.parse(@mock_vdc[:href] + "/catalog") } end shared_examples_for "a tmrk vdc" do @@ -122,14 +122,14 @@ shared_examples_for "the mocked tmrk network links" do describe "[0]" do subject { @vdc.body.networks[0] } it_should_behave_like "a tmrk network link" - its(:href) { should == @mock_vdc[:networks][0][:href] } + its(:href) { should == URI.parse(@mock_vdc[:networks][0][:href]) } its(:name) { should == @mock_vdc[:networks][0][:name] } end describe "[1]" do subject { @vdc.body.networks[1] } it_should_behave_like "a tmrk network link" - its(:href) { should == @mock_vdc[:networks][1][:href] } + its(:href) { should == URI.parse(@mock_vdc[:networks][1][:href]) } its(:name) { should == @mock_vdc[:networks][1][:name] } end end @@ -141,27 +141,29 @@ shared_examples_for "the mocked tmrk resource entity links" do subject { @vdc.body.resource_entities[0] } it_should_behave_like "a vapp type" it_should_behave_like "all vcloud links w/o a rel" - its(:href) { should == @mock_vdc[:vms][0][:href] } + its(:href) { should == URI.parse(@mock_vdc[:vms][0][:href]) } its(:name) { should == @mock_vdc[:vms][0][:name] } end describe "[1]" do subject { @vdc.body.resource_entities[1] } it_should_behave_like "a vapp type" it_should_behave_like "all vcloud links w/o a rel" - its(:href) { should == @mock_vdc[:vms][1][:href] } + its(:href) { should == URI.parse(@mock_vdc[:vms][1][:href]) } its(:name) { should == @mock_vdc[:vms][1][:name] } end describe "[2]" do subject { @vdc.body.resource_entities[2] } it_should_behave_like "a vapp type" it_should_behave_like "all vcloud links w/o a rel" - its(:href) { should == @mock_vdc[:vms][2][:href] } + its(:href) { should == URI.parse(@mock_vdc[:vms][2][:href]) } its(:name) { should == @mock_vdc[:vms][2][:name] } end end Spec::Example::ExampleGroupFactory.register(:vcloud_request, Class.new(Spec::Example::ExampleGroup)) +Spec::Example::ExampleGroupFactory.register(:vcloud_model, Class.new(Spec::Example::ExampleGroup)) Spec::Example::ExampleGroupFactory.register(:tmrk_ecloud_request, Class.new(Spec::Example::ExampleGroup)) +Spec::Example::ExampleGroupFactory.register(:tmrk_ecloud_model, Class.new(Spec::Example::ExampleGroup)) Spec::Example::ExampleGroupFactory.register(:tmrk_vcloud_request, Class.new(Spec::Example::ExampleGroup)) Spec::Runner.configure do |config| @@ -171,14 +173,48 @@ Spec::Runner.configure do |config| @mock_organization = @mock_data[:organizations][0] @mock_vdc = @mock_organization[:vdcs][0] end + config.before(:each, :type => :vcloud_model) do + @vcloud = Fog::Vcloud.new + end config.before(:each, :type => :vcloud_request) do @vcloud = Fog::Vcloud.new end config.before(:each, :type => :tmrk_ecloud_request) do @vcloud = Fog::Vcloud.new(:module => "Fog::Vcloud::Terremark::Ecloud") end + config.before(:each, :type => :tmrk_ecloud_model) do + @vcloud = Fog::Vcloud.new(:module => "Fog::Vcloud::Terremark::Ecloud") + end config.before(:each, :type => :tmrk_vcloud_request) do @vcloud = Fog::Vcloud.new(:module => "Fog::Vcloud::Terremark::Vcloud") end end +Spec::Matchers.define :have_only_these_attributes do |expected| + match do |actual| + attributes = actual.instance_variable_get('@attributes') + attributes.all? { |attribute| expected.include?(attribute) } && ( expected.length == attributes.length ) + end + + failure_message_for_should do |actual| + msg = "Expected: [#{expected.map{|e| ":#{e}"}.join(", ")}]\n" + msg += "Got: [#{actual.instance_variable_get('@attributes').map{|a| ":#{a}"}.join(", ")}]" + msg + end +end + +Spec::Matchers.define :have_identity do |expected| + match do |actual| + actual.instance_variable_get('@identity').should == expected + end + + failure_message_for_should do |actual| + "Expected: '#{expected}', but got: '#{actual.instance_variable_get('@identity')}'" + end +end + +Spec::Matchers.define :have_members_of_the_right_model do + match do |actual| + actual.all? { |member| member.is_a?(actual.model) } + end +end diff --git a/spec/vcloud/terremark/ecloud/models/vdc_spec.rb b/spec/vcloud/terremark/ecloud/models/vdc_spec.rb new file mode 100644 index 000000000..4bbb6e5d3 --- /dev/null +++ b/spec/vcloud/terremark/ecloud/models/vdc_spec.rb @@ -0,0 +1,43 @@ +require File.join(File.dirname(__FILE__),'..','..','..','spec_helper') + +describe "Fog::Vcloud::Terremark::Ecloud::Vdc", :type => :tmrk_ecloud_model do + subject { @vcloud } + + it { should respond_to :get_vdc } + + describe :class do + subject { Fog::Vcloud::Terremark::Ecloud::Vdc } + + it { should have_identity :href } + it { should have_only_these_attributes [:href, :name, :other_links, :resource_entity_links, :network_links, :cpu_capacity, + :storage_capacity, :memory_capacity, :vcloud_type, :xmlns, :description, + :deployed_vm_quota, :instantiated_vm_quota] } + end + + context "with no uri" do + + subject { Fog::Vcloud::Terremark::Ecloud::Vdc.new() } + + its(:href) { should be_nil } + its(:identity) { should be_nil } + end + + context "as a collection member" do + subject { @vcloud.vdcs[0] } + + its(:href) { should == URI.parse(@mock_vdc[:href]) } + its(:identity) { should == URI.parse(@mock_vdc[:href]) } + its(:name) { should == @mock_vdc[:name] } + its(:other_links) { should have(4).items } + its(:resource_entity_links) { should have(3).items } + its(:network_links) { should have(2).items } + + its(:cpu_capacity) { should == Struct::VcloudXCapacity.new('hz * 10^6',@mock_vdc[:cpu][:allocated]) } + its(:memory_capacity) { should == Struct::VcloudXCapacity.new('bytes * 2^20',@mock_vdc[:memory][:allocated]) } + its(:storage_capacity) { should == Struct::VcloudXCapacity.new('bytes * 10^9',@mock_vdc[:storage][:allocated], @mock_vdc[:storage][:used]) } + + its(:deployed_vm_quota) { should == Struct::VcloudXCapacity.new(nil,nil,-1,-1) } + its(:instantiated_vm_quota) { should == Struct::VcloudXCapacity.new(nil,nil,-1,-1) } + + end +end diff --git a/spec/vcloud/terremark/ecloud/models/vdcs_spec.rb b/spec/vcloud/terremark/ecloud/models/vdcs_spec.rb new file mode 100644 index 000000000..96468abe8 --- /dev/null +++ b/spec/vcloud/terremark/ecloud/models/vdcs_spec.rb @@ -0,0 +1,25 @@ +require File.join(File.dirname(__FILE__),'..','..','..','spec_helper') + +describe "Fog::Vcloud::Terremark::Ecloud::Vdcs", :type => :tmrk_ecloud_model do + subject { @vcloud } + + it { should respond_to :vdcs } + + describe :class do + subject { @vcloud.vdcs.class } + its(:model) { should == Fog::Vcloud::Terremark::Ecloud::Vdc } + its(:get_request) { should == :get_vdc } + its(:all_request) { should be_an_instance_of Proc } + its(:vcloud_type) { should == "application/vnd.vmware.vcloud.vdc+xml" } + end + + describe :vdcs do + subject { @vcloud.vdcs } + + it { should be_an_instance_of Fog::Vcloud::Terremark::Ecloud::Vdcs } + + its(:length) { should == 2 } + + it { should have_members_of_the_right_model } + end +end diff --git a/spec/vcloud/terremark/ecloud/requests/get_vdc_spec.rb b/spec/vcloud/terremark/ecloud/requests/get_vdc_spec.rb index acc181d23..fca829904 100644 --- a/spec/vcloud/terremark/ecloud/requests/get_vdc_spec.rb +++ b/spec/vcloud/terremark/ecloud/requests/get_vdc_spec.rb @@ -7,7 +7,7 @@ describe "Fog::Vcloud, initialized w/ the TMRK Ecloud module", :type => :tmrk_ec describe "#get_vdc" do context "with a valid vdc uri" do - before { @vdc = @vcloud.get_vdc(@mock_vdc[:href]) } + before { @vdc = @vcloud.get_vdc(URI.parse(@mock_vdc[:href])) } subject { @vdc } it_should_behave_like "all requests" @@ -33,7 +33,7 @@ describe "Fog::Vcloud, initialized w/ the TMRK Ecloud module", :type => :tmrk_ec it { should respond_to :instantiated_vm_quota } its(:name) { should == @mock_vdc[:name] } - its(:href) { should == @mock_vdc[:href] } + its(:href) { should == URI.parse(@mock_vdc[:href]) } its(:description) { should == '' } describe "#links" do @@ -51,7 +51,7 @@ describe "Fog::Vcloud, initialized w/ the TMRK Ecloud module", :type => :tmrk_ec it_should_behave_like "all rel=down vcloud links" it_should_behave_like "all tmrk ecloud publicIpList links" - specify { subject.href.should == @mock_vdc[:href].sub('/vdc','/extensions/vdc') + "/publicIps" } + specify { subject.href.should == URI.parse(@mock_vdc[:href].sub('/vdc','/extensions/vdc') + "/publicIps") } end describe "[2]" do @@ -60,7 +60,7 @@ describe "Fog::Vcloud, initialized w/ the TMRK Ecloud module", :type => :tmrk_ec it_should_behave_like "all rel=down vcloud links" it_should_behave_like "all tmrk ecloud internetServicesList links" - specify { subject.href.should == @mock_vdc[:href] + "/internetServices" } + specify { subject.href.should == URI.parse(@mock_vdc[:href] + "/internetServices") } end describe "[3]" do @@ -69,7 +69,7 @@ describe "Fog::Vcloud, initialized w/ the TMRK Ecloud module", :type => :tmrk_ec it_should_behave_like "all rel=down vcloud links" it_should_behave_like "all tmrk ecloud firewallAclList links" - specify { subject.href.should == @mock_vdc[:href].sub('/vdc','/extensions/vdc') + "/firewallAcls" } + specify { subject.href.should == URI.parse(@mock_vdc[:href].sub('/vdc','/extensions/vdc') + "/firewallAcls") } end end @@ -96,7 +96,7 @@ describe "Fog::Vcloud, initialized w/ the TMRK Ecloud module", :type => :tmrk_ec describe "#memory_capacity" do subject { @vdc.body.memory_capacity } - it { should be_an_instance_of Struct::TmrkEcloudXCapacity } + it { should be_an_instance_of Struct::VcloudXCapacity } its(:units) { should == "bytes * 2^20" } its(:allocated) { should == @mock_vdc[:memory][:allocated] } its(:used) { should == nil } @@ -105,7 +105,7 @@ describe "Fog::Vcloud, initialized w/ the TMRK Ecloud module", :type => :tmrk_ec describe "#deployed_vm_quota" do subject { @vdc.body.deployed_vm_quota } - it { should be_an_instance_of Struct::TmrkEcloudXCapacity } + it { should be_an_instance_of Struct::VcloudXCapacity } its(:limit) { should == -1 } its(:used) { should == -1 } its(:units) { should == nil } @@ -113,7 +113,7 @@ describe "Fog::Vcloud, initialized w/ the TMRK Ecloud module", :type => :tmrk_ec end describe "#instantiated_vm_quota" do subject { @vdc.body.instantiated_vm_quota } - it { should be_an_instance_of Struct::TmrkEcloudXCapacity } + it { should be_an_instance_of Struct::VcloudXCapacity } its(:limit) { should == -1 } its(:used) { should == -1 } its(:units) { should == nil } diff --git a/spec/vcloud/terremark/vcloud/requests/get_vdc_spec.rb b/spec/vcloud/terremark/vcloud/requests/get_vdc_spec.rb index a201cc233..cc0d5a76d 100644 --- a/spec/vcloud/terremark/vcloud/requests/get_vdc_spec.rb +++ b/spec/vcloud/terremark/vcloud/requests/get_vdc_spec.rb @@ -7,7 +7,7 @@ describe "Fog::Vcloud, initialized w/ the TMRK Vcloud module", :type => :tmrk_vc describe :get_vdc do context "with a valid vdc uri" do - before { @vdc = @vcloud.get_vdc(@mock_vdc[:href]) } + before { @vdc = @vcloud.get_vdc(URI.parse(@mock_vdc[:href])) } subject { @vdc } it_should_behave_like "all requests" @@ -27,7 +27,7 @@ describe "Fog::Vcloud, initialized w/ the TMRK Vcloud module", :type => :tmrk_vc it_should_behave_like "a tmrk vdc" its(:name) { should == @mock_vdc[:name] } - its(:href) { should == @mock_vdc[:href] } + its(:href) { should == URI.parse(@mock_vdc[:href]) } describe "#links" do subject { @vdc.body.links } @@ -43,7 +43,7 @@ describe "Fog::Vcloud, initialized w/ the TMRK Vcloud module", :type => :tmrk_vc it_should_behave_like "all rel=down vcloud links" it_should_behave_like "all vcloud application/xml types" - specify { subject.href.should == @mock_vdc[:href] + "/publicIps" } + specify { subject.href.should == URI.parse(@mock_vdc[:href] + "/publicIps") } end describe "#link[2]" do @@ -51,7 +51,7 @@ describe "Fog::Vcloud, initialized w/ the TMRK Vcloud module", :type => :tmrk_vc it_should_behave_like "all rel=down vcloud links" it_should_behave_like "all vcloud application/xml types" - specify { subject.href.should == @mock_vdc[:href] + "/internetServices" } + specify { subject.href.should == URI.parse(@mock_vdc[:href] + "/internetServices") } end end describe :networks do