vcloud 0.0.1.1

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 (56) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +14 -0
  3. data/Gemfile.lock +39 -0
  4. data/LICENSE +7 -0
  5. data/README.md +53 -0
  6. data/Rakefile +8 -0
  7. data/examples/hello_vcloud.rb +183 -0
  8. data/lib/vcloud.rb +16 -0
  9. data/lib/vcloud/base_vcloud_entity.rb +59 -0
  10. data/lib/vcloud/client.rb +117 -0
  11. data/lib/vcloud/constants.rb +38 -0
  12. data/lib/vcloud/errors.rb +31 -0
  13. data/lib/vcloud/parses_xml.rb +33 -0
  14. data/lib/vcloud/rest_api.rb +91 -0
  15. data/lib/vcloud/user.rb +5 -0
  16. data/lib/vcloud/user/catalog.rb +32 -0
  17. data/lib/vcloud/user/catalog_item.rb +10 -0
  18. data/lib/vcloud/user/error.rb +12 -0
  19. data/lib/vcloud/user/instantiate_vapp_template_params.rb +36 -0
  20. data/lib/vcloud/user/link.rb +30 -0
  21. data/lib/vcloud/user/network_config.rb +20 -0
  22. data/lib/vcloud/user/network_config_section.rb +20 -0
  23. data/lib/vcloud/user/org.rb +69 -0
  24. data/lib/vcloud/user/org_list.rb +10 -0
  25. data/lib/vcloud/user/reference.rb +27 -0
  26. data/lib/vcloud/user/task.rb +54 -0
  27. data/lib/vcloud/user/vapp.rb +103 -0
  28. data/lib/vcloud/user/vdc.rb +32 -0
  29. data/lib/version.rb +3 -0
  30. data/spec/catalog_item_spec.rb +35 -0
  31. data/spec/catalog_spec.rb +62 -0
  32. data/spec/client_spec.rb +87 -0
  33. data/spec/fixtures/catalog.xml +8 -0
  34. data/spec/fixtures/catalog_item.xml +6 -0
  35. data/spec/fixtures/error_login_404.html +24 -0
  36. data/spec/fixtures/instantiate_vapp_template_params.xml +11 -0
  37. data/spec/fixtures/network_config.xml +6 -0
  38. data/spec/fixtures/network_config_section.xml +6 -0
  39. data/spec/fixtures/org.xml +11 -0
  40. data/spec/fixtures/org_list.xml +4 -0
  41. data/spec/fixtures/session.xml +7 -0
  42. data/spec/fixtures/task.xml +6 -0
  43. data/spec/fixtures/vapp.xml +31 -0
  44. data/spec/fixtures/vapp_template.xml +74 -0
  45. data/spec/fixtures/vdc.xml +55 -0
  46. data/spec/instantiate_vapp_template_params_spec.rb +60 -0
  47. data/spec/network_config_section_spec.rb +42 -0
  48. data/spec/network_config_spec.rb +31 -0
  49. data/spec/org_spec.rb +99 -0
  50. data/spec/rest_api_spec.rb +48 -0
  51. data/spec/spec_helper.rb +20 -0
  52. data/spec/task_spec.rb +74 -0
  53. data/spec/vapp_spec.rb +85 -0
  54. data/spec/vdc_spec.rb +83 -0
  55. data/vcloud.gemspec +19 -0
  56. metadata +173 -0
@@ -0,0 +1,27 @@
1
+ module VCloud
2
+ # A reference to a resource. Contains an href attribute and optional name and type attributes.
3
+ class Reference
4
+ include HappyMapper
5
+
6
+ tag '*'
7
+ attribute :id, 'String'
8
+ attribute :type, 'String'
9
+ attribute :name, 'String'
10
+ attribute :href, 'String'
11
+
12
+ def initialize(args = {})
13
+ @rel = args[:id]
14
+ @type = args[:type]
15
+ @name = args[:name]
16
+ @href = args[:href]
17
+ end
18
+
19
+ # Parse a VCloud::Reference from XML
20
+ #
21
+ # @param [String] xml XML to parse
22
+ # @return [VCloud::Reference] Reference that is parsed from the XML
23
+ def self.from_xml(xml)
24
+ parse(xml)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,54 @@
1
+ module VCloud
2
+ # Represents an asynchronous operation in vCloud Director
3
+ class Task < BaseVCloudEntity
4
+ require 'timeout'
5
+
6
+ include ParsesXml
7
+
8
+ has_type VCloud::Constants::ContentType::TASK
9
+ tag 'Task'
10
+ has_links
11
+ has_default_attributes
12
+ attribute :status, String
13
+ attribute :start_time, String, :tag => 'startTime'
14
+ attribute :operation_name, String, :tag => 'operationName'
15
+ attribute :operation, String
16
+ attribute :expiry_time, String, :tag => 'expiryTime'
17
+
18
+ # Wait until the status of the task is set to indicate that the task has completed
19
+ #
20
+ # @param [Integer] timeout Timeout in seconds
21
+ # @yield Block to run upon completion or the timeout is reached, whichever comes first
22
+ def wait_to_finish(timeout = 60 * 10)
23
+ first_run = true
24
+ Timeout::timeout(timeout) do
25
+ until @@completed_statuses.include?(self.status)
26
+ sleep 3 if not first_run
27
+ refresh
28
+ first_run = false
29
+ end
30
+ end
31
+ yield(self) if block_given?
32
+ end
33
+
34
+ # Task status as it's being processed
35
+ module Status
36
+ # The task has been queued for execution
37
+ QUEUED = 'queued'
38
+ # The task is awaiting preprocessing or administrative action
39
+ PRE_RUNNING = 'preRunning'
40
+ # The task is running
41
+ RUNNING = 'running'
42
+ # The task completed with a status of success
43
+ SUCCESS = 'success'
44
+ # The task encountered an error while running
45
+ ERROR = 'error'
46
+ # The task was canceled by the owner or an administrator
47
+ CANCELED = 'canceled'
48
+ # The task was aborted by an administrative action
49
+ ABORTED = 'aborted'
50
+ end
51
+ @@completed_statuses = [Status::SUCCESS, Status::ERROR, Status::CANCELED, Status::ABORTED]
52
+
53
+ end
54
+ end
@@ -0,0 +1,103 @@
1
+ module VCloud
2
+ # A vApp is a collection of VMs, network config, etc.
3
+ class VApp < BaseVCloudEntity
4
+ include ParsesXml
5
+
6
+ has_type VCloud::Constants::ContentType::VAPP
7
+ tag 'VApp'
8
+ has_links
9
+ has_default_attributes
10
+ has_many :tasks, 'VCloud::Task'
11
+
12
+ # Power on all VMs iin the vApp. This operation is available only for a vApp that is powered off.
13
+ #
14
+ # @return [VCloud::Task] Task used to monitor the power on event
15
+ def power_on
16
+ link = links.select{ |l| l.rel == "power:powerOn" }.first
17
+ post_task(link)
18
+ end
19
+
20
+ # def power_off
21
+ # link = links.select{ |l| l.rel == "power:powerOff" }.first
22
+ # post_task(link)
23
+ # end
24
+ #
25
+ # def suspend
26
+ # link = links.select{ |l| l.rel == "power:suspend" }.first
27
+ # post_task(link)
28
+ # end
29
+
30
+ # Delete the vApp
31
+ #
32
+ # @return [VCloud::Task] Task used to monitor the delete vApp event
33
+ def remove
34
+ link = links.select{ |l| l.rel == "remove" }.first
35
+ result = delete(link.href, nil, VCloud::Constants::ACCEPT_HEADER)
36
+ task = VCloud::Task.from_xml(result)
37
+ task.session = session
38
+ task
39
+ end
40
+
41
+ # def deploy
42
+ # link = links.select{ |l| l.rel == "deploy" }.first
43
+ # post_task(link)
44
+ # end
45
+
46
+ # Undeployment deallocates all resources used by the vApp and the VMs it contains
47
+ #
48
+ # @param [VCloud::VApp::UndeployPowerAction] power_action
49
+ # @return [VCloud::Task] Task used to monitor the undeploy vApp event
50
+ def undeploy(power_action)
51
+ undeploy_params = UndeployVAppParams.new
52
+ undeploy_params.undeploy_power_action = power_action
53
+
54
+ link = links.select{ |l| l.rel == "undeploy" }.first
55
+
56
+ result = post(link.href, undeploy_params.to_xml, VCloud::Constants::ContentType::UNDEPLOY_VAPP_PARAMS)
57
+
58
+ task = VCloud::Task.from_xml(result)
59
+ task.session = self.session
60
+ task
61
+ end
62
+
63
+ def parse_xml(xml)
64
+ super xml
65
+ if self.session
66
+ self.tasks.each do |task|
67
+ task.session = self.session
68
+ end
69
+ end
70
+ end
71
+
72
+ def post_task(link)
73
+ result = post(link.href, nil, VCloud::Constants::ACCEPT_HEADER)
74
+ task = VCloud::Task.from_xml(result)
75
+ task.session = self.session
76
+ task
77
+ end
78
+
79
+ # The specified action is applied to all VMs in the vApp.
80
+ # All values other than 'default' ignore actions, order, and delay specified in the StartupSection.
81
+ module UndeployPowerAction
82
+ # Power off the VMs. This is the default action if this attribute is missing or empty)
83
+ POWER_OFF = 'powerOff'
84
+ # Suspend the VMs
85
+ SUSPEND = 'suspend'
86
+ # Shut down the VMs
87
+ SHUTDOWN = 'shutdown'
88
+ # Attempt to power off the VMs. Failures in undeploying the VM or associated networks are ignored. All references to the vApp and its VMs are removed from the database
89
+ FORCE = 'force'
90
+ # Use the actions, order, and delay specified in the StartupSection
91
+ DEFAULT = 'default'
92
+ end
93
+
94
+ end
95
+
96
+ # Paramater passed when undeploying a VApp
97
+ class UndeployVAppParams
98
+ include HappyMapper
99
+ register_namespace 'xmlns', VCloud::Constants::NameSpace::V1_5
100
+ tag 'UndeployVAppParams'
101
+ element :undeploy_power_action, String, :tag => 'UndeployPowerAction'
102
+ end
103
+ end
@@ -0,0 +1,32 @@
1
+ module VCloud
2
+ # Represents the user view of an organization vDC
3
+ class Vdc < BaseVCloudEntity
4
+ include ParsesXml
5
+
6
+ has_type VCloud::Constants::ContentType::VDC
7
+ tag 'Vdc'
8
+ has_default_attributes
9
+ has_links
10
+ has_many :network_references, 'VCloud::Reference', :tag => 'Network'
11
+
12
+ # Returns a hash of of all Network references, keyed by the name
13
+ #
14
+ # @return [Hash{String => VCloud::Reference}] Reference to all Networks in the vDC, keyed by name
15
+ def get_network_references_by_name
16
+ Hash[@network_references.collect{ |i| [i.name, i] }]
17
+ end
18
+
19
+ # Create a vApp from a vApp template
20
+ #
21
+ # @param [VCloud::InstantiateVAppTemplateParams] instantiate_vapp_template_params vApp template params
22
+ # @param [VCloud::Client] session Session to create the vApp Template under
23
+ # @return [VCloud::VApp] vApp that was created
24
+ def instantiate_vapp_template(instantiate_vapp_template_params, session = self.session)
25
+ url = @links.select{ |l| l.type == VCloud::Constants::ContentType::INSTANTIATE_VAPP_TEMPLATE_PARAMS }.first.href
26
+ response = post(url, instantiate_vapp_template_params.to_xml, VCloud::Constants::ContentType::INSTANTIATE_VAPP_TEMPLATE_PARAMS, session)
27
+ vapp = VCloud::VApp.new :session => session
28
+ vapp.parse_xml(response)
29
+ vapp
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ module VCloud
2
+ VERSION = "0.0.1.1"
3
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ include WebMock::API
4
+
5
+ describe VCloud::CatalogItem do
6
+ describe "when parsing #from_xml" do
7
+ before(:each) do
8
+ @item = VCloud::CatalogItem.from_xml(fixture_file('catalog_item.xml'))
9
+ end
10
+
11
+ it 'should have correct values' do
12
+ @item.name.should == 'Ubuntu 10.04.4 LTS'
13
+ @item.id.should == 'urn:vcloud:catalogitem:aaa-bbb-ccc-ddd-eee-fff'
14
+ @item.type.should == 'application/vnd.vmware.vcloud.catalogItem+xml'
15
+ @item.href.should == 'https://some.vcloud.com/api/catalogItem/aaa-bbb-ccc-ddd-eee-fff'
16
+ @item.links.should have(2).items
17
+ @item.entity_reference.name.should == 'Ubuntu 10.04.4 LTS'
18
+ @item.entity_reference.href.should == 'https://some.vcloud.com/api/vAppTemplate/vappTemplate-aaa-bbb-ccc-ddd-eee-fff'
19
+ @item.entity_reference.type.should == 'application/vnd.vmware.vcloud.vAppTemplate+xml'
20
+ end
21
+ end
22
+
23
+ it 'should retrieve CatalogItem #from_reference' do
24
+ stub_request(:get, "https://vcloud.diebold.dev/api/catalogItem/aaa-bbb-ccc-ddd-eee-fff").
25
+ with(:headers => {'Accept'=>'application/vnd.vmware.vcloud.catalogItem+xml;version=1.5', 'X-Vcloud-Authorization'=>'abc123xyz'}).
26
+ to_return(:status => 200, :body => fixture_file('catalog_item.xml'))
27
+
28
+ item = VCloud::CatalogItem.from_reference(stub(:href => 'https://vcloud.diebold.dev/api/catalogItem/aaa-bbb-ccc-ddd-eee-fff'), @session)
29
+
30
+ WebMock.should have_requested(:get, 'https://vcloud.diebold.dev/api/catalogItem/aaa-bbb-ccc-ddd-eee-fff').
31
+ with(:headers => {'Accept'=>'application/vnd.vmware.vcloud.catalogItem+xml;version=1.5', 'X-Vcloud-Authorization'=>'abc123xyz'})
32
+
33
+ item.id.should == 'urn:vcloud:catalogitem:aaa-bbb-ccc-ddd-eee-fff'
34
+ end
35
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ include WebMock::API
4
+
5
+ describe VCloud::Catalog do
6
+ before(:each) do
7
+ @catalog = VCloud::Catalog.from_xml(fixture_file('catalog.xml'))
8
+ end
9
+
10
+ describe 'parses xml' do
11
+ it '#from_xml should have correct values' do
12
+ @catalog.name.should == 'SuperCool Catalog'
13
+ @catalog.id.should == 'urn:vcloud:catalog:aaa-bbb-ccc-ddd-eee-fff'
14
+ @catalog.type.should == 'application/vnd.vmware.vcloud.catalog+xml'
15
+ @catalog.href.should == 'https://some.vcloud.com/api/catalog/aaa-bbb-ccc-ddd-eee-fff'
16
+ @catalog.links.should have(1).items
17
+ @catalog.catalog_item_references.should have(1).items
18
+ @catalog.is_published.should == true
19
+ end
20
+
21
+ it 'should #get_catalog_item_references_by_name' do
22
+ hash = @catalog.get_catalog_item_references_by_name
23
+
24
+ hash.should have(1).items
25
+ hash['Ubuntu 10.04.4 LTS'].href.should == 'https://some.vcloud.com/api/catalogItem/aaa-bbb-ccc-ddd-eee-fff'
26
+ end
27
+ end
28
+
29
+ it 'should #get_catalog_item_from_name if name exists' do
30
+ ref = @catalog.get_catalog_item_references_by_name()['Ubuntu 10.04.4 LTS']
31
+ VCloud::CatalogItem.should_receive(:from_reference).with(ref, @session).and_return('not nil')
32
+
33
+ item = @catalog.get_catalog_item_from_name('Ubuntu 10.04.4 LTS', @session)
34
+
35
+ item.should_not be_nil
36
+ end
37
+
38
+ it 'should return nil #get_catalog_item_from_name if name does not exist' do
39
+ item = @catalog.get_catalog_item_from_name('not exist')
40
+
41
+ item.should be_nil
42
+ end
43
+
44
+ it "should retrieve catalog #from_reference" do
45
+ stub_request(:get, "https://vcloud.diebold.dev/api/catalog/aaa-bbb-ccc-ddd-eee-fff").
46
+ with(:headers => {'Accept'=>'application/vnd.vmware.vcloud.catalog+xml;version=1.5', 'X-Vcloud-Authorization'=>'abc123xyz'}).
47
+ to_return(:status => 200, :body => fixture_file('catalog.xml'))
48
+
49
+ catalog = VCloud::Catalog.from_reference(stub(:href => 'https://vcloud.diebold.dev/api/catalog/aaa-bbb-ccc-ddd-eee-fff'), @session)
50
+
51
+ WebMock.should have_requested(:get, 'https://vcloud.diebold.dev/api/catalog/aaa-bbb-ccc-ddd-eee-fff').
52
+ with(:headers => {'Accept'=>'application/vnd.vmware.vcloud.catalog+xml;version=1.5', 'X-Vcloud-Authorization'=>'abc123xyz'})
53
+
54
+ @catalog.name.should == 'SuperCool Catalog'
55
+ @catalog.id.should == 'urn:vcloud:catalog:aaa-bbb-ccc-ddd-eee-fff'
56
+ @catalog.type.should == 'application/vnd.vmware.vcloud.catalog+xml'
57
+ @catalog.href.should == 'https://some.vcloud.com/api/catalog/aaa-bbb-ccc-ddd-eee-fff'
58
+ @catalog.links.should have(1).items
59
+ @catalog.catalog_item_references.should have(1).items
60
+ @catalog.is_published.should == true
61
+ end
62
+ end
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ include WebMock::API
4
+
5
+ describe VCloud::Client do
6
+
7
+ it "should login" do
8
+ stub_request(:post, "https://someuser%40someorg:password@some.vcloud.com/api/sessions").
9
+ with(:headers => {'Accept'=>'application/*+xml;version=1.5'}).
10
+ to_return(:status => 200, :body => fixture_file('session.xml'), :headers => {:x_vcloud_authorization => "abc123xyz"})
11
+
12
+ test_session = VCloud::Client.new('https://some.vcloud.com/api/', '1.5')
13
+ test_session.login('someuser@someorg', 'password')
14
+
15
+ test_session.url.should == 'https://some.vcloud.com/api/'
16
+ test_session.api_version.should == '1.5'
17
+ test_session.user.should == 'someuser'
18
+ test_session.org.should == 'someorg'
19
+ test_session.type.should == 'application/vnd.vmware.vcloud.session+xml'
20
+ test_session.href.should == 'https://some.vcloud.com/api/session/'
21
+ test_session.token.should_not be_nil
22
+ test_session.token[:x_vcloud_authorization].should == "abc123xyz"
23
+ test_session.links.should have(4).items
24
+ test_session.logged_in?.should == true
25
+ end
26
+
27
+ it "should #get_org_references" do
28
+ stub_request(:get, "https://some.vcloud.com/api/org/").
29
+ with(:headers => {'Accept'=>'application/vnd.vmware.vcloud.orgList+xml;version=1.5', 'X-Vcloud-Authorization'=>'abc123xyz'}).
30
+ to_return(:status => 200, :body => fixture_file('org_list.xml'))
31
+
32
+ org_refs = @session.get_org_references
33
+
34
+ WebMock.should have_requested(:get, "https://some.vcloud.com/api/org/").
35
+ with(:headers => {'Accept'=>'application/vnd.vmware.vcloud.orgList+xml;version=1.5', 'X-Vcloud-Authorization'=>'abc123xyz'})
36
+
37
+ org_refs.should have(1).items
38
+ org_refs.first.name.should == "someorg"
39
+ org_refs.first.href.should == "https://some.vcloud.com/api/org/aaa-bbb-ccc-ddd-eee-fff"
40
+ end
41
+
42
+ it "should #get_org_references_by_name" do
43
+ stub_request(:get, "https://some.vcloud.com/api/org/").
44
+ with(:headers => {'Accept'=>'application/vnd.vmware.vcloud.orgList+xml;version=1.5', 'X-Vcloud-Authorization'=>'abc123xyz'}).
45
+ to_return(:status => 200, :body => fixture_file('org_list.xml'))
46
+
47
+ hash = @session.get_org_references_by_name
48
+
49
+ hash.should have(1).items
50
+ hash['someorg'].should_not be_nil
51
+ end
52
+
53
+ it "should #get_org_from_name if name exists" do
54
+ stub_request(:get, "https://some.vcloud.com/api/org/").
55
+ with(:headers => {'Accept'=>'application/vnd.vmware.vcloud.orgList+xml;version=1.5', 'X-Vcloud-Authorization'=>'abc123xyz'}).
56
+ to_return(:status => 200, :body => fixture_file('org_list.xml'))
57
+
58
+ VCloud::Org.should_receive(:from_reference).and_return("not nil")
59
+
60
+ org = @session.get_org_from_name('someorg')
61
+
62
+ org.should_not be_nil
63
+ end
64
+
65
+ it "should return nil #get_org_from_name if name does not exist" do
66
+ stub_request(:get, "https://some.vcloud.com/api/org/").
67
+ with(:headers => {'Accept'=>'application/vnd.vmware.vcloud.orgList+xml;version=1.5', 'X-Vcloud-Authorization'=>'abc123xyz'}).
68
+ to_return(:status => 200, :body => fixture_file('org_list.xml'))
69
+
70
+ VCloud::Org.should_not_receive(:from_reference)
71
+
72
+ org = @session.get_org_from_name('no_such_org')
73
+
74
+ org.should be_nil
75
+ end
76
+
77
+ it "should #logout and destroy the session" do
78
+ stub_request(:delete, "https://some.vcloud.com/api/session").
79
+ with(:headers => {'Accept'=>'application/*+xml;version=1.5', 'X-Vcloud-Authorization'=>'abc123xyz'}).
80
+ to_return(:status => 204, :body => "", :headers => {})
81
+
82
+ @session.logout
83
+
84
+ @session.logged_in?.should == false
85
+ @session.token.should == nil
86
+ end
87
+ end
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Catalog xmlns="http://www.vmware.com/vcloud/v1.5" name="SuperCool Catalog" id="urn:vcloud:catalog:aaa-bbb-ccc-ddd-eee-fff" type="application/vnd.vmware.vcloud.catalog+xml" href="https://some.vcloud.com/api/catalog/aaa-bbb-ccc-ddd-eee-fff" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://127.0.0.1/api/v1.5/schema/master.xsd">
3
+ <Link rel="down" type="application/vnd.vmware.vcloud.metadata+xml" href="https://some.vcloud.com/api/catalog/aaa-bbb-ccc-ddd-eee-fff/metadata"/>
4
+ <CatalogItems>
5
+ <CatalogItem type="application/vnd.vmware.vcloud.catalogItem+xml" name="Ubuntu 10.04.4 LTS" href="https://some.vcloud.com/api/catalogItem/aaa-bbb-ccc-ddd-eee-fff"/>
6
+ </CatalogItems>
7
+ <IsPublished>true</IsPublished>
8
+ </Catalog>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CatalogItem xmlns="http://www.vmware.com/vcloud/v1.5" name="Ubuntu 10.04.4 LTS" id="urn:vcloud:catalogitem:aaa-bbb-ccc-ddd-eee-fff" type="application/vnd.vmware.vcloud.catalogItem+xml" href="https://some.vcloud.com/api/catalogItem/aaa-bbb-ccc-ddd-eee-fff" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://127.0.0.1/api/v1.5/schema/master.xsd">
3
+ <Link rel="up" type="application/vnd.vmware.vcloud.catalog+xml" href="https://some.vcloud.com/api/catalog/aaa-bbb-ccc-ddd-eee-fff"/>
4
+ <Link rel="down" type="application/vnd.vmware.vcloud.metadata+xml" href="https://some.vcloud.com/api/catalogItem/aaa-bbb-ccc-ddd-eee-fff/metadata"/>
5
+ <Entity type="application/vnd.vmware.vcloud.vAppTemplate+xml" name="Ubuntu 10.04.4 LTS" href="https://some.vcloud.com/api/vAppTemplate/vappTemplate-aaa-bbb-ccc-ddd-eee-fff"/>
6
+ </CatalogItem>
@@ -0,0 +1,24 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+
3
+
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="mul">
6
+
7
+ <head>
8
+ <title>VMware vCloud Director</title>
9
+ <link rel="shortcut icon" href="/favicon.ico" />
10
+ </head>
11
+ <body style="background-color: #555; padding: 0; margin: 0;">
12
+ <div id="container">
13
+ <div style="float: right; padding-right: "><img width="104" height="104" src="/i/cornerMosaic.png" /></div>
14
+ <div style="padding: 15px 0px 3px 15px;"><img width="61" height="10" src="/i/vmware.png" /></div>
15
+ <img width="48" height="48" style="display: inline; padding: 2px 15px 3px 15px;" src="/i/logoLarge.png" />
16
+ <span style="color: #fff; font-size: 16pt; font-weight: bold; font-family: sans-serif;">Page not found.</span>
17
+ <div>
18
+ <span style="color: #fff; font-size: 16pt; font-weight: bold; font-family: sans-serif;">
19
+
20
+ </span>
21
+ </div>
22
+ </div>
23
+ </body>
24
+ </html>