vcloud 0.0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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>