1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00

[vcloud_director] Mocking for tasks.

This commit is contained in:
Nick Osborn 2013-10-20 19:52:14 +01:00
parent 17a3b98c60
commit 10b0ef3f25
19 changed files with 1206 additions and 172 deletions

View file

@ -187,7 +187,7 @@ module Fog
request :get_vm_pending_question
request :get_vms
request :get_vms_by_metadata
request :get_vms_disks_attached_to
request :get_vms_disk_attached_to
request :get_vms_in_lease_from_query
request :instantiate_vapp_template # to be deprecated
request :post_acquire_ticket
@ -231,6 +231,7 @@ module Fog
request :post_update_vapp_metadata
request :post_update_vapp_template_metadata
request :post_upgrade_hw_version
request :post_upload_disk
request :post_upload_media
request :post_upload_vapp_template
request :put_catalog_item_metadata_item_metadata
@ -482,6 +483,7 @@ module Fog
:name => 'vAppTemplate 1'
}
},
:disks => {},
:edge_gateways => {
uuid => {
:name => 'MockEdgeGateway',
@ -627,6 +629,63 @@ module Fog
[8,4,4,4,12].map {|i| Fog::Mock.random_hex(i)}.join('-')
end
# Create a task.
#
# @param [String] operation A message describing the operation that is
# tracked by this task.
# @param [String] operation_name The short name of the operation that
# is tracked by this task.
# @param [Hash] owner Reference to the owner of the task. This is
# typically the object that the task is creating or updating.
# * :href<~String> - Contains the URI to the entity.
# * :type<~String> - Contains the MIME type of the entity.
# @return [String] Object identifier of the task.
def enqueue_task(operation, operation_name, owner, options={})
task_id = uuid
now = DateTime.now
data[:tasks][task_id] = {
:cancel_requested => false,
:details => '',
:expiry_time => now + 86400, # in 24 hours
:name => 'task',
:progress => 1,
:service_namespace => 'com.vmware.vcloud',
:start_time => now,
:status => 'running',
}.merge(options).merge(
:operation => operation,
:operation_name => operation_name,
:owner => owner
)
task_id
end
# @note As far as this method is concerned, the only possible task
# states are 'running' and 'success'.
#
# @param [Hash] response_body
# @return [Boolean]
def process_task(response_body)
task_id = response_body[:href].split('/').last
task = data[:tasks][task_id]
if task[:status] == 'running'
task[:end_time] = DateTime.now
task[:progress] = 100
task[:status] = 'success'
if task[:on_success]
task[:on_success].call
task.delete(:on_success)
end
end
return true if task[:status] == 'success'
raise TaskError.new "status: #{task[:status]}, error: #{task[:Error]}"
end
def add_id_from_href!(data={})
data[:id] = data[:href].split('/').last
end

View file

@ -22,6 +22,39 @@ module Fog
)
end
end
class Mock
def delete_disk(id)
unless data[:disks][id]
raise Fog::Compute::VcloudDirector::Forbidden.new(
"No access to entity \"(com.vmware.vcloud.entity.disk:#{id})\""
)
end
owner = {
:href => make_href("disk/#{id}"),
:type => 'application/vnd.vmware.vcloud.disk+xml'
}
task_id = enqueue_task(
"Deleting Disk(#{id})", 'vdcDeleteDisk', owner,
:on_success => lambda do
data[:disks].delete(id)
end
)
body = {
:xmlns => xmlns,
:xmlns_xsi => xmlns_xsi,
:xsi_schemaLocation => xsi_schema_location,
}.merge(task_body(task_id))
Excon::Response.new(
:status => 202,
:headers => {'Content-Type' => "#{body[:type]};version=#{api_version}"},
:body => body
)
end
end
end
end
end

View file

@ -10,6 +10,67 @@ module Fog
# @param [String] id Object identifier of the media object.
# @return [Excon::Response]
# * body<~Hash>:
# * :href<~String> - The URI of the entity.
# * :type<~String> - The MIME type of the entity.
# * :id<~String> - The entity identifier, expressed in URN format.
# The value of this attribute uniquely identifies the entity,
# persists for the life of the entity, and is never reused.
# * :operationKey<~String> - Optional unique identifier to support
# idempotent semantics for create and delete operations.
# * :name<~String> - The name of the entity.
# * :cancelRequested<~String> - Whether user has requested this
# processing to be canceled.
# * :endTime<~String> - The date and time that processing of the
# task was completed. May not be present if the task is still
# being executed.
# * :expiryTime<~String> - The date and time at which the task
# resource will be destroyed and no longer available for
# retrieval. May not be present if the task has not been executed
# or is still being executed.
# * :operation<~String> - A message describing the operation that
# is tracked by this task.
# * :operationName<~String> - The short name of the operation that
# is tracked by this task.
# * :serviceNamespace<~String> - Identifier of the service that
# created the task.
# * :startTime<~String> - The date and time the system started
# executing the task. May not be present if the task has not been
# executed yet.
# * :status<~String> - The execution status of the task.
# * :Link<~Array<Hash>>:
# * :Description<~String> - Optional description.
# * :Owner<~Hash> - Reference to the owner of the task. This is
# typically the object that the task is creating or updating.
# * :href<~String> - Contains the URI to the entity.
# * :name<~String> - Contains the name of the entity.
# * :type<~String> - Contains the type of the entity.
# * :Error<~Hash> - Represents error information from a failed
# task.
# * :majorErrorCode<~String> - The class of the error. Matches
# the HTTP status code.
# * :message<~String> - An one line, human-readable message
# describing the error that occurred.
# * :minorErrorCode<~String> - Resource-specific error code.
# * :stackTrace<~String> - The stack trace of the exception.
# * :vendorSpecificErrorCode<~String> - A vendor- or
# implementation-specific error code that can reference
# specific modules or source lines for diagnostic purposes.
# * :User<~Hash> - The user who started the task.
# * :href<~String> - Contains the URI to the entity.
# * :name<~String> - Contains the name of the entity.
# * :type<~String> - Contains the type of the entity.
# * :Organization<~Hash> - The organization to which the :User
# belongs.
# * :href<~String> - Contains the URI to the entity.
# * :name<~String> - Contains the name of the entity.
# * :type<~String> - Contains the type of the entity.
# * :Progress<~String> - Read-only indicator of task progress as
# an approximate percentage between 0 and 100. Not available
# for all tasks.
# * :Params
# * :Details<~String> - Detailed message about the task. Also
# contained by the :Owner entity when task status is
# preRunning.
#
# @raise [Fog::Compute::VcloudDirector::Forbidden]
#
@ -33,8 +94,27 @@ module Fog
)
end
Fog::Mock.not_implemented
media.is_used_here # avoid warning from syntax checker
owner = {
:href => make_href("media/#{id}"),
:type => 'application/vnd.vmware.vcloud.media+xml'
}
task_id = enqueue_task(
"Deleting Media File(#{media[:file][:uuid]})", 'vdcDeleteMedia', owner,
:on_success => lambda do
data[:medias].delete(id)
end
)
body = {
:xmlns => xmlns,
:xmlns_xsi => xmlns_xsi,
:xsi_schemaLocation => xsi_schema_location,
}.merge(task_body(task_id))
Excon::Response.new(
:status => 202,
:headers => {'Content-Type' => "#{body[:type]};version=#{api_version}"},
:body => body
)
end
end
end

View file

@ -7,17 +7,115 @@ module Fog
# @param [String] id Object identifier of the disk.
# @return [Excon::Response]
# * body<~Hash>:
# * :href<~String> - The URI of the disk.
# * :type<~String> - The MIME type of the disk.
# * :id<~String> - The disk identifier, expressed in URN format.
# * :name<~String> - The name of the disk.
# * :status<~String> - Creation status of the disk.
# * :busSubType<~String> - Disk bus sub type.
# * :busType<~String> - Disk bus type.
# * :size<~String> - Size of the disk.
# * :Description<~String> - Optional description.
# * :Tasks<~Hash> - A list of queued, running, or recently
# completed tasks associated with this disk.
# * :StorageProfile<~Hash> - Storage profile of the disk.
# * :Owner<~Hash> - Disk owner.
#
# @raise [Fog::Compute::VcloudDirector::Forbidden]
#
# @see http://pubs.vmware.com/vcd-51/topic/com.vmware.vcloud.api.reference.doc_51/doc/operations/GET-Disk.html
# @since vCloud API version 5.1
def get_disk(id)
request(
response = request(
:expects => 200,
:idempotent => true,
:method => 'GET',
:parser => Fog::ToHashDocument.new,
:path => "disk/#{id}"
)
ensure_list! response.body, :Link
ensure_list! response.body, :Tasks, :Task
#ensure_list! response.body, :Files, :File
response
end
end
class Mock
def get_disk(id)
unless data[:disks][id]
raise Fog::Compute::VcloudDirector::Forbidden.new(
'No access to entity "com.vmware.vcloud.entity.disk:%s".' % id
)
end
body = {
:xmlns => xmlns,
:xmlns_xsi => xmlns_xsi,
:xsi_schemaLocation => xsi_schema_location
}.merge(disk_body(id))
Excon::Response.new(
:status => 200,
:headers => {'Content-Type' => "#{body[:type]};version=#{@version}"},
:body => body
)
end
private
def disk_body(id)
disk = data[:disks][id]
storage_class_id = disk[:vdc_storage_class]
body = {
:href => make_href("disk/#{id}"),
:type => 'application/vnd.vmware.vcloud.disk+xml',
:id => "urn:vcloud:disk:#{id}",
:name => disk[:name],
:status => disk[:status].to_s,
:busSubType => disk[:bus_sub_type],
:busType => disk[:bus_type],
:size => disk[:size].to_s,
:Link => [
{
:href => make_href("vdc/#{disk[:vdc_id]}"),
:rel => 'up',
:type => 'application/vnd.vmware.vcloud.vdc+xml'
}
],
:Description => disk[:description],
:Tasks => {
# FIXME: there's only one for now
:Task => disk[:tasks].map {|task_id| task_body(task_id)}.first
},
:Files => {
:File => []
},
:StorageProfile => {
:href => make_href("vdcStorageProfile/#{storage_class_id}"),
:name => data[:vdc_storage_classes][storage_class_id][:name],
:type => 'application/vnd.vmware.vcloud.vdcStorageProfile+xml',
},
:Owner => {
:type => 'application/vnd.vmware.vcloud.owner+xml',
:User => {
:href => make_href("admin/user/#{user_uuid}"),
:name => user_name,
:type => 'application/vnd.vmware.admin.user+xml',
}
}
}
if api_version.to_f >= 5.1
storage_class_id = disk[:vdc_storage_class]
body[:VdcStorageProfile] = {
:href => make_href("vdcStorageProfile/#{storage_class_id}"),
:name => data[:vdc_storage_classes][storage_class_id][:name],
:type => 'application/vnd.vmware.vcloud.vdcStorageProfile+xml',
}
end
body
end
end
end

View file

@ -7,6 +7,19 @@ module Fog
# @param [String] id Object identifier of the disk.
# @return [Excon::Response]
# * body<~Hash>:
# * :href<~String> - The URI of the disk.
# * :type<~String> - The MIME type of the disk.
# * :Link<~Hash>:
# * :href<~String> -
# * :type<~String> -
# * :rel<~String> -
# * :User<~Hash> - Reference to the user who is the owner of this
# disk.
# * :href<~String> - The URI of the user.
# * :name<~String> - The name of the user.
# * :type<~String> - The MIME type of the user.
#
# @raise [Fog::Compute::VcloudDirector::Forbidden]
#
# @see http://pubs.vmware.com/vcd-51/topic/com.vmware.vcloud.api.reference.doc_51/doc/operations/GET-DiskOwner.html
# @since vCloud API version 5.1
@ -20,6 +33,38 @@ module Fog
)
end
end
class Mock
def get_disk_owner(id)
unless data[:disks][id]
raise Fog::Compute::VcloudDirector::Forbidden.new(
'No access to entity "com.vmware.vcloud.entity.disk:%s".' % id
)
end
body = {
:xmlns => xmlns,
:xmlns_xsi => xmlns_xsi,
:xsi_schemaLocation => xsi_schema_location,
:Link => {
:href => make_href("disk/#{id}"),
:type => 'application/vnd.vmware.vcloud.disk+xml',
:rel => 'up'
},
:User => {
:href => make_href("admin/user/#{user_uuid}"),
:name => user_name,
:type => 'application/vnd.vmware.admin.user+xml',
}
}
Excon::Response.new(
:status => 200,
:headers => {'Content-Type' => "#{body[:type]};version=#{@version}"},
:body => body
)
end
end
end
end
end

View file

@ -13,26 +13,97 @@ module Fog
# @see http://pubs.vmware.com/vcd-51/topic/com.vmware.vcloud.api.reference.doc_51/doc/operations/GET-Media.html
# @since vCloud API version 0.9
def get_media(id)
request(
response = request(
:expects => 200,
:idempotent => true,
:method => 'GET',
:parser => Fog::ToHashDocument.new,
:path => "media/#{id}"
)
ensure_list! response.body, :Files, :File
response
end
end
class Mock
def get_media(id)
unless media = data[:medias][id]
unless data[:medias][id]
raise Fog::Compute::VcloudDirector::Forbidden.new(
"No access to entity \"(com.vmware.vcloud.entity.media:#{id})\"."
)
end
Fog::Mock.not_implemented
media.is_used_here # avoid warning from syntax checker
body = {
:xmlns => xmlns,
:xmlns_xsi => xmlns_xsi,
:xsi_schemaLocation => xsi_schema_location
}.merge(media_body(id))
Excon::Response.new(
:status => 200,
:headers => {'Content-Type' => "#{body[:type]};version=>#{@api_version}"},
:body => body
)
end
private
def media_body(id)
media = data[:medias][id]
body = {
:size => media[:size].to_s,
:imageType => media[:image_type],
:status => media[:status].to_s,
:name => media[:name],
:id => "urn:vcloud:media:#{id}",
:type => 'application/vnd.vmware.vcloud.media+xml',
:href => make_href("media/#{id}"),
:Link => {
:href => make_href("vdc/#{media[:vdc_id]}"),
:type => 'application/vnd.vmware.vcloud.vdc+xml',
:rel => 'up'
},
:Description => media[:description] || '',
:Tasks => {
# FIXME: there's only one for now
:Task => media[:tasks].map {|task_id| task_body(task_id)}.first
},
:Files => {
:File => []
},
:Owner => {
:type => 'application/vnd.vmware.vcloud.owner+xml',
:User => {
:href => make_href("admin/user/#{user_uuid}"),
:name => user_uuid,
:type => 'application/vnd.vmware.admin.user+xml',
}
}
}
if media[:status] == 0
body[:Files][:File] << {
:size => media[:size].to_s,
:bytesTransferred => media[:file][:bytes_transferred].to_s,
:name => 'file',
:Link=> {
:href => make_href("transfer/#{media[:file][:uuid]}/file"),
:rel => 'upload:default'
}
}
end
if api_version.to_f >= 5.1
storage_class_id = media[:vdc_storage_class]
body[:VdcStorageProfile] = {
:href => make_href("vdcStorageProfile/#{storage_class_id}"),
:name => data[:vdc_storage_classes][storage_class_id][:name],
:type => 'application/vnd.vmware.vcloud.vdcStorageProfile+xml',
}
end
body
end
end
end

View file

@ -7,6 +7,17 @@ module Fog
# @param [String] id Object identifier of the media object.
# @return [Excon::Response]
# * body<~Hash>:
# * :href<~String> - The URI of the media object.
# * :type<~String> - The MIME type of the media object.
# * :Link<~Hash>:
# * :href<~String> -
# * :type<~String> -
# * :rel<~String> -
# * :User<~Hash> - Reference to the user who is the owner of this
# media object.
# * :href<~String> - The URI of the user.
# * :name<~String> - The name of the user.
# * :type<~String> - The MIME type of the user.
#
# @raise [Fog::Compute::VcloudDirector::Forbidden]
#
@ -25,14 +36,33 @@ module Fog
class Mock
def get_media_owner(id)
unless media = data[:medias][id]
unless data[:medias][id]
raise Fog::Compute::VcloudDirector::Forbidden.new(
"No access to entity \"com.vmware.vcloud.entity.media:#{id}\"."
'No access to entity "com.vmware.vcloud.entity.media:%s".' % id
)
end
Fog::Mock.not_implemented
media.is_used_here # avoid warning from syntax checker
body = {
:xmlns => xmlns,
:xmlns_xsi => xmlns_xsi,
:xsi_schemaLocation => xsi_schema_location,
:Link => {
:href => make_href("media/#{id}"),
:type => 'application/vnd.vmware.vcloud.media+xml',
:rel => 'up'
},
:User => {
:href => make_href("admin/user/#{user_uuid}"),
:name => user_name,
:type => 'application/vnd.vmware.admin.user+xml',
}
}
Excon::Response.new(
:status => 200,
:headers => {'Content-Type' => "#{body[:type]};version=#{@version}"},
:body => body
)
end
end
end

View file

@ -1,3 +1,5 @@
require 'date'
module Fog
module Compute
class VcloudDirector
@ -7,6 +9,66 @@ module Fog
# @param [String] id The object identifier of the task.
# @return [Excon::Response]
# * body<~Hash>:
# * :href<~String> - The URI of the entity.
# * :type<~String> - The MIME type of the entity.
# * :id<~String> - The entity identifier, expressed in URN format.
# The value of this attribute uniquely identifies the entity,
# persists for the life of the entity, and is never reused.
# * :operationKey<~String> - Optional unique identifier to support
# idempotent semantics for create and delete operations.
# * :name<~String> - The name of the entity.
# * :cancelRequested<~String> - Whether user has requested this
# processing to be canceled.
# * :endTime<~String> - The date and time that processing of the
# task was completed. May not be present if the task is still
# being executed.
# * :expiryTime<~String> - The date and time at which the task
# resource will be destroyed and no longer available for
# retrieval. May not be present if the task has not been executed
# or is still being executed.
# * :operation<~String> - A message describing the operation that
# is tracked by this task.
# * :operationName<~String> - The short name of the operation that
# is tracked by this task.
# * :serviceNamespace<~String> - Identifier of the service that
# created the task.
# * :startTime<~String> - The date and time the system started
# executing the task. May not be present if the task has not been
# executed yet.
# * :status<~String> - The execution status of the task.
# * :Link<~Array<Hash>>:
# * :Description<~String> - Optional description.
# * :Owner<~Hash> - Reference to the owner of the task. This is
# typically the object that the task is creating or updating.
# * :href<~String> - Contains the URI to the entity.
# * :name<~String> - Contains the name of the entity.
# * :type<~String> - Contains the type of the entity.
# * :Error<~Hash> - Represents error information from a failed
# task.
# * :majorErrorCode<~String> - The class of the error. Matches
# the HTTP status code.
# * :message<~String> - An one line, human-readable message
# describing the error that occurred.
# * :minorErrorCode<~String> - Resource-specific error code.
# * :stackTrace<~String> - The stack trace of the exception.
# * :vendorSpecificErrorCode<~String> - A vendor- or
# implementation-specific error code that can reference
# specific modules or source lines for diagnostic purposes.
# * :User<~Hash> - The user who started the task.
# * :href<~String> - Contains the URI to the entity.
# * :name<~String> - Contains the name of the entity.
# * :type<~String> - Contains the type of the entity.
# * :Organization<~Hash> - The organization to which the :User
# belongs.
# * :href<~String> - Contains the URI to the entity.
# * :name<~String> - Contains the name of the entity.
# * :type<~String> - Contains the type of the entity.
# * :Progress<~String> - Read-only indicator of task progress as an
# approximate percentage between 0 and 100. Not available for all
# tasks.
# * :Params
# * :Details<~String> - Detailed message about the task. Also
# contained by the :Owner entity when task status is preRunning.
#
# @raise [Fog::Compute::VcloudDirector::Forbidden]
#
@ -25,14 +87,71 @@ module Fog
class Mock
def get_task(id)
unless task = data[:tasks][id]
unless data[:tasks][id]
raise Fog::Compute::VcloudDirector::Forbidden.new(
'This operation is denied.'
)
end
Fog::Mock.not_implemented
task.is_used_here # avoid warning from syntax checker
body = {
:xmlns => xmlns,
:xmlns_xsi => xmlns_xsi,
:xsi_schemaLocation => xsi_schema_location
}.merge(task_body(id))
Excon::Response.new(
:status => 200,
:headers => {'Type' => "application/#{body[:type]};version=#{api_version}"},
:body => body
)
end
private
# @param [String] id Object identifier of the task.
# @return [Hash]
def task_body(id)
task = data[:tasks][id]
body = {
:href => make_href("tasks/#{id}"),
:type => 'application/vnd.vmware.vcloud.task+xml',
:id => "urn:vcloud:tasl:#{id}",
:name => task[:name],
:cancelRequested => task[:cancel_requested].to_s,
:expiryTime => task[:expiry_time].iso8601,
:operation => task[:operation],
:operationName => task[:operation_name],
:serviceNamespace => task[:service_namespace],
:status => task[:status],
:Link => [],
:Owner => task[:owner],
:User => { # for now, always the current user
:href => make_href("admin/user/#{user_uuid}"),
:name => user_name,
:type => 'application/vnd.vmware.admin.user+xml',
},
:Organization => { # for now, always the current org
:href => make_href("org/#{data[:org][:uuid]}"),
:name => data[:org][:name],
:type => 'application/vnd.vmware.vcloud.org+xml',
},
:Progress => task[:progress].to_s,
:Details => task[:details] || '',
}
body[:endTime] = task[:end_time].iso8601 if task[:end_time]
body[:startTime] = task[:start_time].iso8601 if task[:start_time]
body[:Description] = task[:description] if task[:description]
if task[:status] == 'running'
body[:Link] << {
:href => make_href("task/#{id}/action/cancel"),
:type => 'application/vnd.vmware.vcloud.task+xml',
:rel => 'cancel',
}
end
body
end
end
end

View file

@ -11,7 +11,78 @@ module Fog
# @param [String] id Object identifier of the organization.
# @return [Excon::Response]
# * body<~Hash>:
# * :href<~String> - The URI of the entity.
# * :type<~String> - The MIME type of the entity.
# * :id<~String> - The entity identifier, expressed in URN format.
# The value of this attribute uniquely identifies the entity,
# persists for the life of the entity, and is never reused.
# * :name<~String> - The name of the entity.
# * :Task<~Array<Hash>>:
# * :href<~String> - The URI of the entity.
# * :type<~String> - The MIME type of the entity.
# * :id<~String> - The entity identifier, expressed in URN
# format. The value of this attribute uniquely identifies the
# entity, persists for the life of the entity, and is never
# reused.
# * :operationKey<~String> - Optional unique identifier to
# support idempotent semantics for create and delete
# operations.
# * :name<~String> - The name of the entity.
# * :cancelRequested<~String> - Whether user has requested this
# processing to be canceled.
# * :endTime<~String> - The date and time that processing of the
# task was completed. May not be present if the task is still
# being executed.
# * :expiryTime<~String> - The date and time at which the task
# resource will be destroyed and no longer available for
# retrieval. May not be present if the task has not been
# executed or is still being executed.
# * :operation<~String> - A message describing the operation that
# is tracked by this task.
# * :operationName<~String> - The short name of the operation
# that is tracked by this task.
# * :serviceNamespace<~String> - Identifier of the service that
# created the task.
# * :startTime<~String> - The date and time the system started
# executing the task. May not be present if the task has not
# been executed yet.
# * :status<~String> - The execution status of the task.
# * :Link<~Array<Hash>>:
# * :Description<~String> - Optional description.
# * :Owner<~Hash> - Reference to the owner of the task. This is
# typically the object that the task is creating or updating.
# * :href<~String> - Contains the URI to the entity.
# * :name<~String> - Contains the name of the entity.
# * :type<~String> - Contains the type of the entity.
# * :Error<~Hash> - Represents error information from a failed
# task.
# * :majorErrorCode<~String> - The class of the error. Matches
# the HTTP status code.
# * :message<~String> - An one line, human-readable message
# describing the error that occurred.
# * :minorErrorCode<~String> - Resource-specific error code.
# * :stackTrace<~String> - The stack trace of the exception.
# * :vendorSpecificErrorCode<~String> - A vendor- or
# implementation-specific error code that can reference
# specific modules or source lines for diagnostic purposes.
# * :User<~Hash> - The user who started the task.
# * :href<~String> - Contains the URI to the entity.
# * :name<~String> - Contains the name of the entity.
# * :type<~String> - Contains the type of the entity.
# * :Organization<~Hash> - The organization to which the :User
# belongs.
# * :href<~String> - Contains the URI to the entity.
# * :name<~String> - Contains the name of the entity.
# * :type<~String> - Contains the type of the entity.
# * :Progress<~String> - Read-only indicator of task progress as
# an approximate percentage between 0 and 100. Not available
# for all tasks.
# * :Params
# * :Details<~String> - Detailed message about the task. Also
# contained by the :Owner entity when task status is
# preRunning.
#
# @raise [Fog::Compute::VcloudDirector::BadRequest]
# @raise [Fog::Compute::VcloudDirector::Forbidden]
#
# @see http://pubs.vmware.com/vcd-51/topic/com.vmware.vcloud.api.reference.doc_51/doc/operations/GET-TaskList.html
@ -37,43 +108,15 @@ module Fog
)
end
body =
{:xmlns=>xmlns,
:xmlns_xsi=>xmlns_xsi,
:name=>"Tasks Lists",
:type=>"application/vnd.vmware.vcloud.tasksList+xml",
:href=>make_href("tasksList/#{id}"),
:xsi_schemaLocation=>xsi_schema_location}
tasks = data[:tasks].map do |task_id, task|
{:status => task[:status],
:startTime => task[:startTime].iso8601,
:operationName => task[:operationName],
:operation => task[:operation],
:expiryTime => task[:expiryTime].utc.iso8601,
:endTime => task[:endTime].iso8601,
:cancelRequested => task[:cancelRequested].to_s,
:name => task[:name],
:id => "urn:vcloud:task:#{id}",
:type => 'application/vnd.vmware.vcloud.task+xml',
:href => make_href("task/#{task_id}"),
:Owner =>
{:type => "application/vnd.vmware.vcloud.vApp+xml",
:name => "vApp_#{user_name}_0",
:href=> make_href("vApp/vapp-#{uuid}")},
:User =>
{:type => "application/vnd.vmware.admin.user+xml",
:name => user_name,
:href => make_href("admin/user/#{user_uuid}")},
:Organization =>
{:type => "application/vnd.vmware.vcloud.org+xml",
:name => org_name,
:href => make_href("org/#{org_uuid}")},
:Progress => task[:Progress].to_s,
:Details => task[:Details] || ''}
end
tasks = tasks.first if tasks.size == 1
body[:Task] = tasks
body = {
:xmlns => xmlns,
:xmlns_xsi => xmlns_xsi,
:xsi_schemaLocation => xsi_schema_location,
:href => make_href("tasksList/#{id}"),
:type => "application/vnd.vmware.vcloud.tasksList+xml",
:name => "Tasks Lists",
:Task => data[:tasks].keys.map {|task_id| task_body(task_id)}
}
Excon::Response.new(
:status => 200,

View file

@ -10,14 +10,28 @@ module Fog
#
# @see http://pubs.vmware.com/vcd-51/topic/com.vmware.vcloud.api.reference.doc_51/doc/operations/GET-VmsDisksAttachedTo.html
# @since vCloud API version 5.1
def get_vms_disks_attached_to(id)
request(
def get_vms_disk_attached_to(id)
response = request(
:expects => 200,
:idempotent => true,
:method => 'GET',
:parser => Fog::ToHashDocument.new,
:path => "disk/#{id}/attachedVms"
)
ensure_list! response.body, :VmReference
response
end
end
class Mock
def get_vms_disk_attached_to(id)
unless data[:disks][id]
raise Fog::Compute::VcloudDirector::Forbidden.new(
'No access to entity "com.vmware.vcloud.entity.disk:%s".' % id
)
end
Fog::Mock.not_implemented
end
end
end

View file

@ -20,6 +20,24 @@ module Fog
)
end
end
class Mock
def post_cancel_task(id)
unless task = data[:tasks][id]
raise Fog::Compute::VcloudDirector::Forbidden.new(
'No access to entity "com.vmware.vcloud.entity.task:%s"' % id
)
end
# @note Tasks don't actually get cancelled (confirmed VCloud Director
# bug) so we'll emulate that. Set the flag and we're done!
task[:cancel_requested] = true
Excon::Response.new(
:status => 204
)
end
end
end
end
end

View file

@ -36,7 +36,7 @@ module Fog
}
end.to_xml
request(
response = request(
:body => body,
:expects => 201,
:headers => {'Content-Type' => 'application/vnd.vmware.vcloud.cloneMediaParams+xml'},
@ -44,6 +44,57 @@ module Fog
:parser => Fog::ToHashDocument.new,
:path => "vdc/#{vdc_id}/action/cloneMedia"
)
ensure_list! response.body, :Files, :File
response
end
end
class Mock
def post_clone_media(vdc_id, source_id, options={})
# TODO: check this happens.
unless source_media = data[:medias][source_id]
raise Fog::Compute::VcloudDirector::Forbidden.new(
"No access to entity \"(com.vmware.vcloud.entity.media:#{source_id})\"."
)
end
unless data[:vdcs][vdc_id]
raise Fog::Compute::VcloudDirector::Forbidden.new(
"No access to entity \"(com.vmware.vcloud.entity.vdc:#{vdc_id})\"."
)
end
media_id = uuid
media_name = "#{source_media[:name]}-copy-#{uuid}"
owner = {
:href => make_href("media/#{media_id}"),
:type => 'application/vnd.vmware.vcloud.media+xml'
}
task_id = enqueue_task(
"Copy Media File #{media_name}(#{media_id})", 'vdcCopyMedia', owner,
:on_success => lambda do
data[:medias][media_id][:status] = 1
end
)
media = source_media.dup.merge(
:name => media_name,
:status => 0,
:tasks => [task_id]
)
data[:medias][media_id] = media
body = {
:xmlns => xmlns,
:xmlns_xsi => xmlns_xsi,
:xsi_schemaLocation => xsi_schema_location
}.merge(media_body(media_id))
Excon::Response.new(
:status => 201,
:headers => {'Content-Type' => "#{body[:type]};version=#{api_version}"},
:body => body
)
end
end
end

View file

@ -0,0 +1,133 @@
module Fog
module Compute
class VcloudDirector
class Real
# Create a disk.
#
# @param [String] id Object identifier of the vDC.
# @param [String] name The name of the disk.
# @param [Integer] size Size of the disk. For modify operation this is
# required only for the XSD validation it could not be changed.
# @param [Hash] options
# @option options [String] :operationKey Optional unique identifier to
# support idempotent semantics for create and delete operations.
# @option options [Integer] :busSubType Disk bus sub type.
# @option options [Integer] :busType Disk bus type.
# @option options [String] :Description Optional description.
# @return [Excon::Response]
# * body<~Hash>:
# * :href<~String> - The URI of the disk.
# * :type<~String> - The MIME type of the disk.
# * :id<~String> - The disk identifier, expressed in URN format.
# * :operationKey<~String> - Optional unique identifier to support
# idempotent semantics for create and delete operations.
# * :name<~String> - The name of the disk.
# * :status<~String> - Creation status of the disk.
# * :busSubType<~String> - Disk bus sub type.
# * :busType<~String> - Disk bus type.
# * :size<~String> - Size of the disk.
# * :Link:
# * :Description<~String> - Optional description.
# * :Tasks<~Hash>:
# * :StorageProfile<~Hash> - Storage profile of the disk.
# * :href<~String> - Contains the URI to the entity.
# * :name<~String> - Contains the name of the entity.
# * :type<~String> - Contains the type of the entity.
# * :Owner<~Hash> - Disk owner.
# * :type<~String> - The MIME type of the entity.
# * :User<~Hash> - Reference to the user who is the owner of this
# disk.
# * :href<~String> - Contains the URI to the entity.
# * :name<~String> - Contains the name of the entity.
# * :type<~String> - Contains the type of the entity.
#
# @see http://pubs.vmware.com/vcd-51/topic/com.vmware.vcloud.api.reference.doc_51/doc/operations/POST-CreateDisk.html
# @since vCloud API version 5.1
def post_upload_disk(id, name, size, options={})
body = Nokogiri::XML::Builder.new do
DiskCreateParams(:xmlns => 'http://www.vmware.com/vcloud/v1.5') {
attrs = {
:name => name,
:size => size
}
attrs[:operationKey] = options[:operationKey] if options.key?(:operationKey)
attrs[:busSubType] = options[:busSubType] if options.key?(:busSubType)
attrs[:busType] = options[:busType] if options.key?(:busType)
Disk(attrs) {
if options.key?(:Description)
Description options[:Description]
end
if options.key?(:StorageProfile)
attrs = {
:href => options[:StorageProfile][:href]
}
StorageProfile(attrs)
end
}
}
end.to_xml
request(
:body => body,
:expects => 201,
:headers => {'Content-Type' => 'application/vnd.vmware.vcloud.diskCreateParams+xml'},
:method => 'POST',
:parser => Fog::ToHashDocument.new,
:path => "vdc/#{id}/disk"
)
end
end
class Mock
def post_upload_disk(id, name, size, options={})
unless size.to_s =~ /^\d+$/
raise Fog::Compute::VcloudDirector::BadRequest.new(
"validation error on field 'diskSpec.sizeBytes': must be greater than or equal to 0"
)
end
unless data[:vdcs][id]
raise Fog::Compute::VcloudDirector::Forbidden.new(
'No access to entity "(com.vmware.vcloud.entity.vdc:%s)".' % id
)
end
disk_id = uuid
owner = {
:href => make_href("disk/#{disk_id}"),
:type => 'application/vnd.vmware.vcloud.disk+xml'
}
task_id = enqueue_task(
"Creating Disk #{name}(#{disk_id})", 'vdcCreateDisk', owner,
:on_success => lambda do
data[:disks][disk_id][:status] = 1
end
)
disk = {
:description => options[:Description],
:name => name,
:size => size.to_i,
:status => 0,
:tasks => [task_id],
:vdc_id => id,
:vdc_storage_class => data[:vdc_storage_classes].detect {|k,v| v[:default]}.first
}
data[:disks][disk_id] = disk
body = {
:xmlns => xmlns,
:xmlns_xsi => xmlns_xsi,
:xsi_schemaLocation => xsi_schema_location
}.merge(disk_body(disk_id))
Excon::Response.new(
:status => 201,
:headers => {'Content-Type' => "#{body[:type]};version=#{api_version}"},
:body => body
)
end
end
end
end
end

View file

@ -22,6 +22,7 @@ module Fog
#
# @see http://pubs.vmware.com/vcd-51/topic/com.vmware.vcloud.api.reference.doc_51/doc/operations/POST-UploadMedia.html
# @since vCloud API version 0.9
# @todo Support vDC Storage Profiles.
def post_upload_media(vdc_id, name, image_type, size, options={})
body = Nokogiri::XML::Builder.new do
attrs = {
@ -38,7 +39,7 @@ module Fog
}
end.to_xml
request(
response = request(
:body => body,
:expects => 201,
:headers => {'Content-Type' => 'application/vnd.vmware.vcloud.media+xml'},
@ -46,6 +47,8 @@ module Fog
:parser => Fog::ToHashDocument.new,
:path => "vdc/#{vdc_id}/media"
)
ensure_list! response.body, :Files, :File
response
end
end
@ -61,14 +64,55 @@ module Fog
'validation error on field \'size\': must be greater than or equal to 0'
)
end
unless vdc = data[:vdcs][vdc_id]
unless data[:vdcs][vdc_id]
raise Fog::Compute::VcloudDirector::Forbidden.new(
"No access to entity \"(com.vmware.vcloud.entity.vdc:#{vdc_id})\"."
)
end
Fog::Mock.not_implemented
vdc.is_used_here # avoid warning from syntax checker
media_id = uuid
file_id = uuid
owner = {
:href => make_href("media/#{media_id}"),
:type => 'application/vnd.vmware.vcloud.media+xml'
}
task_id = enqueue_task(
"Importing Media File #{name}(#{file_id})", 'vdcUploadMedia', owner,
:on_success => lambda do
media = data[:medias][media_id]
media[:file][:bytes_transferred] = media[:size]
media[:status] = 1
end
)
media = {
:description => options[:Description],
:file => {
:bytes_transferred => 0,
:uuid => file_id
},
:image_type => image_type,
:name => name,
:size => size.to_i,
:status => 0,
:tasks => [task_id],
:vdc_id => vdc_id,
:vdc_storage_class => data[:vdc_storage_classes].detect {|k,v| v[:default]}.first
}
data[:medias][media_id] = media
body = {
:xmlns => xmlns,
:xmlns_xsi => xmlns_xsi,
:xsi_schemaLocation => xsi_schema_location
}.merge(media_body(media_id))
Excon::Response.new(
:status => 201,
:headers => {'Content-Type' => "#{body[:type]};version=#{api_version}"},
:body => body
)
end
end
end

View file

@ -1,6 +1,166 @@
Shindo.tests('Compute::VcloudDirector | disk requests', ['vclouddirector']) do
@service = Fog::Compute::VcloudDirector.new
@disk_name = VcloudDirector::Compute::Helper.test_name
tests('error conditions') do
tests('#post_upload_disk') do
tests('Invalid size').raises(Fog::Compute::VcloudDirector::BadRequest) do
@service.post_upload_disk('00000000-0000-0000-0000-000000000000', @disk_name, -1)
end
end
tests('Upload to non-existent vDC').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.post_upload_disk('00000000-0000-0000-0000-000000000000', @disk_name, 0)
end
tests('Retrieve non-existent Disk').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.get_disk('00000000-0000-0000-0000-000000000000')
end
tests('Retrieve owner of non-existent Disk').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.get_disk_owner('00000000-0000-0000-0000-000000000000')
end
tests('Retrieve VM list for non-existent Disk').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.get_vms_disk_attached_to('00000000-0000-0000-0000-000000000000')
end
tests('Delete non-existent Disk').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.delete_disk('00000000-0000-0000-0000-000000000000')
end
end
@org = VcloudDirector::Compute::Helper.current_org(@service)
@size = 1024
tests('Upload and manipulate a disk') do
tests('#post_upload_disk').data_matches_schema(VcloudDirector::Compute::Schema::DISK_TYPE) do
@vdc_id = VcloudDirector::Compute::Helper.first_vdc_id(@org)
@disk = @service.post_upload_disk(@vdc_id, @disk_name, @size).body
end
@service.process_task(@disk[:Tasks][:Task])
@disk_id = @disk[:href].split('/').last
tests("#get_disk(#{@disk_id})").data_matches_schema(VcloudDirector::Compute::Schema::DISK_TYPE) do
@disk = @service.get_disk(@disk_id).body
end
tests("disk[:name]").returns(@disk_name) { @disk[:name] }
tests("disk[:size]").returns(@size) { @disk[:size].to_i }
tests("#get_disk_owner(#{@disk_id})").data_matches_schema(VcloudDirector::Compute::Schema::OWNER_TYPE) do
@owner = @service.get_disk_owner(@disk_id).body
end
tests("owner[:User][:name]").returns(@service.user_name) { @owner[:User][:name] }
#tests("#put_disk(#{@disk_id})").data_matches_schema(VcloudDirector::Compute::Schema::TASK_TYPE) do
# @disk_name += '-renamed'
# @task = @service.put_disk(@disk_id, @disk_name).body
#end
#@service.process_task(@task)
#tests("#get_disk(#{@disk_id})").data_matches_schema(VcloudDirector::Compute::Schema::DISK_TYPE) do
# @disk = @service.get_disk(@disk_id).body
#end
#tests("disk[:name]").returns(@disk_name) { @disk[:name] }
#tests("disk[:size]").returns(@size) { @disk[:size].to_i } # shouldn't change
tests('disk metadata') do
pending if Fog.mocking?
tests("#put_disk_metadata_item_metadata(#{@disk_id})").data_matches_schema(VcloudDirector::Compute::Schema::TASK_TYPE) do
@task = @service.put_disk_metadata_item_metadata(@disk_id, 'fog-test-key', 'fog-test-value').body
end
@service.process_task(@task)
tests("#put_disk_metadata_item_metadata(#{@disk_id})") do
tests("#put_disk_metadata_item_metadata(Boolean)").returns(true) do
task = @service.put_disk_metadata_item_metadata(@disk_id, 'fog-test-boolean', true).body
@service.process_task(task)
end
tests("#put_disk_metadata_item_metadata(DateTime)").returns(true) do
task = @service.put_disk_metadata_item_metadata(@disk_id, 'fog-test-datetime', DateTime.now).body
@service.process_task(task)
end
tests("#put_disk_metadata_item_metadata(Number)").returns(true) do
task = @service.put_disk_metadata_item_metadata(@disk_id, 'fog-test-number', 111).body
@service.process_task(task)
end
end
tests("#post_update_disk_metadata(#{@disk_id})").data_matches_schema(VcloudDirector::Compute::Schema::TASK_TYPE) do
metadata = {
'fog-test-key-update' => 'fog-test-value-update',
'fog-test-boolean-update' => false,
'fog-test-datetime-update' => DateTime.now,
'fog-test-number-update' => 222
}
@task = @service.post_update_disk_metadata(@disk_id, metadata).body
end
@service.process_task(@task)
tests("#get_disk_metadata(#{@disk_id})") do
tests('response format').data_matches_schema(VcloudDirector::Compute::Schema::METADATA_TYPE) do
@metadata = @service.get_disk_metadata(@disk_id).body
end
tests('TypedValue') do
pending if @service.api_version.to_f < 5.1
tests('key').returns('MetadataStringValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-key'}
entry[:TypedValue][:xsi_type]
end
tests('boolean').returns('MetadataBooleanValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-boolean'}
entry[:TypedValue][:xsi_type]
end
tests('datetime').returns('MetadataDateTimeValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-datetime'}
entry[:TypedValue][:xsi_type]
end
tests('number').returns('MetadataNumberValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-number'}
entry[:TypedValue][:xsi_type]
end
tests('key-update').returns('MetadataStringValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-key-update'}
entry[:TypedValue][:xsi_type]
end
tests('boolean-update').returns('MetadataBooleanValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-boolean-update'}
entry[:TypedValue][:xsi_type]
end
tests('datetime-update').returns('MetadataDateTimeValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-datetime-update'}
entry[:TypedValue][:xsi_type]
end
tests('number-update').returns('MetadataNumberValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-number-update'}
entry[:TypedValue][:xsi_type]
end
end
end
end
tests("#get_vms_disk_attached_to(#{@disk_id})").data_matches_schema(VcloudDirector::Compute::Schema::VMS_TYPE) do
pending if Fog.mocking?
@service.get_vms_disk_attached_to(@disk_id).body
end
tests("#delete_disk(#{@disk_id})").data_matches_schema(VcloudDirector::Compute::Schema::TASK_TYPE) do
@task = @service.delete_disk(@disk_id).body
end
@service.process_task(@task)
end
tests('Disk no longer exists') do
tests("#get_disk(#{@disk_id})").raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.get_disk(@disk_id)
end
tests("#get_disk_owner(#{@disk_id})").raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.get_disk_owner(@disk_id)
end
tests("#get_disk_metadata(#{@disk_id})").raises(Fog::Compute::VcloudDirector::Forbidden) do
pending if Fog.mocking?
@service.get_disk_metadata(@disk_id)
end
tests("#delete_disk(#{@disk_id})").raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.delete_disk(@disk_id)
end
end
tests('#get_disks_from_query') do
pending if Fog.mocking?
@ -15,9 +175,4 @@ Shindo.tests('Compute::VcloudDirector | disk requests', ['vclouddirector']) do
end
end
tests('Retrieve non-existent Disk').raises(Fog::Compute::VcloudDirector::Forbidden) do
pending if Fog.mocking?
@service.get_disk('00000000-0000-0000-0000-000000000000')
end
end

View file

@ -11,11 +11,15 @@ class VcloudDirector
end
def self.current_org(service)
service.get_organization(current_org_id(service)).body
end
def self.current_org_id(service)
session = service.get_current_session.body
link = session[:Link].detect do |l|
l[:type] == 'application/vnd.vmware.vcloud.org+xml'
end
service.get_organization(link[:href].split('/').last).body
link[:href].split('/').last
end
def self.first_vdc_id(org)

View file

@ -1,31 +1,59 @@
Shindo.tests('Compute::VcloudDirector | media requests', ['vclouddirector']) do
@service = Fog::Compute::VcloudDirector.new
tests('error conditions') do
tests('#post_upload_media') do
tests('Invalid image_type').raises(Fog::Compute::VcloudDirector::BadRequest) do
@service.post_upload_media('00000000-0000-0000-0000-000000000000', 'test.iso', 'isox', 0)
end
tests('Invalid size').raises(Fog::Compute::VcloudDirector::BadRequest) do
@service.post_upload_media('00000000-0000-0000-0000-000000000000', 'test.iso', 'iso', -1)
end
end
tests('Upload to non-existent vDC').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.post_upload_media('00000000-0000-0000-0000-000000000000', 'test.iso', 'iso', 0)
end
tests('Retrieve non-existent Media').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.get_media('00000000-0000-0000-0000-000000000000')
end
tests('Retrieve owner of non-existent Media').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.get_media_owner('00000000-0000-0000-0000-000000000000')
end
tests('Delete non-existent Media').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.delete_media('00000000-0000-0000-0000-000000000000')
end
end
@org = VcloudDirector::Compute::Helper.current_org(@service)
@media_name = VcloudDirector::Compute::Helper.test_name
tests('Upload and manipulate a media object') do
pending if Fog.mocking?
File.open(VcloudDirector::Compute::Helper.fixture('test.iso'), 'rb') do |iso|
tests('#post_upload_media').data_matches_schema(VcloudDirector::Compute::Schema::MEDIA_TYPE) do
@vdc_id = VcloudDirector::Compute::Helper.first_vdc_id(@org)
@media = @service.post_upload_media(@vdc_id, @media_name, 'iso', iso.size).body
end
tests('media object has an upload link').returns(true) do
@link = @media[:Files][:File][:Link]
tests('media object has exactly one file').returns(true) do
@media[:Files][:File].size == 1
end
tests('media object file has an upload link').returns(true) do
@link = @media[:Files][:File].first[:Link]
@link[:rel] == 'upload:default'
end
headers = {
'Content-Length' => iso.size,
'Content-Type' => 'application/octet-stream',
'x-vcloud-authorization' => @service.vcloud_token
}
Excon.put(
@link[:href], :body => iso.read, :expects => 200, :headers => headers
)
unless Fog.mocking?
headers = {
'Content-Length' => iso.size,
'Content-Type' => 'application/octet-stream',
'x-vcloud-authorization' => @service.vcloud_token
}
Excon.put(
@link[:href], :body => iso.read, :expects => 200, :headers => headers
)
end
@service.process_task(@media[:Tasks][:Task])
@media_id = @media[:href].split('/').last
@ -42,74 +70,78 @@ Shindo.tests('Compute::VcloudDirector | media requests', ['vclouddirector']) do
end
tests("owner[:User][:name]").returns(@service.user_name) { @owner[:User][:name] }
tests("#put_media_metadata_item_metadata(#{@media_id})").data_matches_schema(VcloudDirector::Compute::Schema::TASK_TYPE) do
@task = @service.put_media_metadata_item_metadata(@media_id, 'fog-test-key', 'fog-test-value').body
end
@service.process_task(@task)
tests('media metadata') do
pending if Fog.mocking?
tests("#put_media_metadata_item_metadata(#{@media_id})") do
tests("#put_media_metadata_item_metadata(Boolean)").returns(true) do
task = @service.put_media_metadata_item_metadata(@media_id, 'fog-test-boolean', true).body
@service.process_task(task)
tests("#put_media_metadata_item_metadata(#{@media_id})").data_matches_schema(VcloudDirector::Compute::Schema::TASK_TYPE) do
@task = @service.put_media_metadata_item_metadata(@media_id, 'fog-test-key', 'fog-test-value').body
end
tests("#put_media_metadata_item_metadata(DateTime)").returns(true) do
task = @service.put_media_metadata_item_metadata(@media_id, 'fog-test-datetime', DateTime.now).body
@service.process_task(task)
end
tests("#put_media_metadata_item_metadata(Number)").returns(true) do
task = @service.put_media_metadata_item_metadata(@media_id, 'fog-test-number', 111).body
@service.process_task(task)
end
end
@service.process_task(@task)
tests("#post_update_media_metadata(#{@media_id})").data_matches_schema(VcloudDirector::Compute::Schema::TASK_TYPE) do
metadata = {
'fog-test-key-update' => 'fog-test-value-update',
'fog-test-boolean-update' => false,
'fog-test-datetime-update' => DateTime.now,
'fog-test-number-update' => 222
}
@task = @service.post_update_media_metadata(@media_id, metadata).body
end
@service.process_task(@task)
tests("#get_media_metadata(#{@media_id})") do
tests('response format').data_matches_schema(VcloudDirector::Compute::Schema::METADATA_TYPE) do
@metadata = @service.get_media_metadata(@media_id).body
tests("#put_media_metadata_item_metadata(#{@media_id})") do
tests("#put_media_metadata_item_metadata(Boolean)").returns(true) do
task = @service.put_media_metadata_item_metadata(@media_id, 'fog-test-boolean', true).body
@service.process_task(task)
end
tests("#put_media_metadata_item_metadata(DateTime)").returns(true) do
task = @service.put_media_metadata_item_metadata(@media_id, 'fog-test-datetime', DateTime.now).body
@service.process_task(task)
end
tests("#put_media_metadata_item_metadata(Number)").returns(true) do
task = @service.put_media_metadata_item_metadata(@media_id, 'fog-test-number', 111).body
@service.process_task(task)
end
end
tests('TypedValue') do
pending if @service.api_version.to_f < 5.1
tests('key').returns('MetadataStringValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-key'}
entry[:TypedValue][:xsi_type]
tests("#post_update_media_metadata(#{@media_id})").data_matches_schema(VcloudDirector::Compute::Schema::TASK_TYPE) do
metadata = {
'fog-test-key-update' => 'fog-test-value-update',
'fog-test-boolean-update' => false,
'fog-test-datetime-update' => DateTime.now,
'fog-test-number-update' => 222
}
@task = @service.post_update_media_metadata(@media_id, metadata).body
end
@service.process_task(@task)
tests("#get_media_metadata(#{@media_id})") do
tests('response format').data_matches_schema(VcloudDirector::Compute::Schema::METADATA_TYPE) do
@metadata = @service.get_media_metadata(@media_id).body
end
tests('boolean').returns('MetadataBooleanValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-boolean'}
entry[:TypedValue][:xsi_type]
end
tests('datetime').returns('MetadataDateTimeValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-datetime'}
entry[:TypedValue][:xsi_type]
end
tests('number').returns('MetadataNumberValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-number'}
entry[:TypedValue][:xsi_type]
end
tests('key-update').returns('MetadataStringValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-key-update'}
entry[:TypedValue][:xsi_type]
end
tests('boolean-update').returns('MetadataBooleanValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-boolean-update'}
entry[:TypedValue][:xsi_type]
end
tests('datetime-update').returns('MetadataDateTimeValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-datetime-update'}
entry[:TypedValue][:xsi_type]
end
tests('number-update').returns('MetadataNumberValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-number-update'}
entry[:TypedValue][:xsi_type]
tests('TypedValue') do
pending if @service.api_version.to_f < 5.1
tests('key').returns('MetadataStringValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-key'}
entry[:TypedValue][:xsi_type]
end
tests('boolean').returns('MetadataBooleanValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-boolean'}
entry[:TypedValue][:xsi_type]
end
tests('datetime').returns('MetadataDateTimeValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-datetime'}
entry[:TypedValue][:xsi_type]
end
tests('number').returns('MetadataNumberValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-number'}
entry[:TypedValue][:xsi_type]
end
tests('key-update').returns('MetadataStringValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-key-update'}
entry[:TypedValue][:xsi_type]
end
tests('boolean-update').returns('MetadataBooleanValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-boolean-update'}
entry[:TypedValue][:xsi_type]
end
tests('datetime-update').returns('MetadataDateTimeValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-datetime-update'}
entry[:TypedValue][:xsi_type]
end
tests('number-update').returns('MetadataNumberValue') do
entry = @metadata[:MetadataEntry].detect {|e| e[:Key] == 'fog-test-number-update'}
entry[:TypedValue][:xsi_type]
end
end
end
end
@ -131,7 +163,6 @@ Shindo.tests('Compute::VcloudDirector | media requests', ['vclouddirector']) do
end
tests('Media item no longer exists') do
pending if Fog.mocking?
tests("#get_media(#{@media_id})").raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.get_media(@media_id)
end
@ -139,6 +170,7 @@ Shindo.tests('Compute::VcloudDirector | media requests', ['vclouddirector']) do
@service.get_media_owner(@media_id)
end
tests("#get_media_metadata(#{@media_id})").raises(Fog::Compute::VcloudDirector::Forbidden) do
pending if Fog.mocking?
@service.get_media_metadata(@media_id)
end
tests("#delete_media(#{@media_id})").raises(Fog::Compute::VcloudDirector::Forbidden) do
@ -159,27 +191,4 @@ Shindo.tests('Compute::VcloudDirector | media requests', ['vclouddirector']) do
end
end
tests('Invalid image_type').raises(Fog::Compute::VcloudDirector::BadRequest) do
@service.post_upload_media('00000000-0000-0000-0000-000000000000', 'test.iso', 'isox', 0)
end
tests('Invalid size').raises(Fog::Compute::VcloudDirector::BadRequest) do
@service.post_upload_media('00000000-0000-0000-0000-000000000000', 'test.iso', 'iso', -1)
end
tests('Upload to non-existent vDC').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.post_upload_media('00000000-0000-0000-0000-000000000000', 'test.iso', 'iso', 0)
end
tests('Retrieve non-existent Media').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.get_media('00000000-0000-0000-0000-000000000000')
end
tests('Retrieve owner of non-existent Media').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.get_media_owner('00000000-0000-0000-0000-000000000000')
end
tests('Delete non-existent Media').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.delete_media('00000000-0000-0000-0000-000000000000')
end
end

View file

@ -81,7 +81,7 @@ class VcloudDirector
# Represents a list of files to be transferred (uploaded or downloaded).
FILES_LIST_TYPE = {
:File => FILE_TYPE
:File => [FILE_TYPE]
}
# Container for query result sets.
@ -123,7 +123,7 @@ class VcloudDirector
:status => Fog::Nullable::String,
:Description => Fog::Nullable::String,
# :Tasks => TASKS_IN_PROGRESS_TYPE,
# :Files => FILES_LIST_TYPE
# :Files => FILES_LIST_TYPE
})
# Container for references to ResourceEntity objects in this vDC.
@ -620,6 +620,19 @@ class VcloudDirector
:RoleReferences => ROLE_REFERENCES_TYPE,
:Networks => NETWORKS_TYPE
})
# Represents a named disk.
DISK_TYPE = RESOURCE_ENTITY_TYPE.merge({
:busSubType => Fog::Nullable::String,
:busType => Fog::Nullable::String,
:size => String,
:StorageProfile => REFERENCE_TYPE,
:Owner => OWNER_TYPE
})
VMS_TYPE = RESOURCE_TYPE.merge({
:VmReference => [REFERENCE_TYPE]
})
end
end
end

View file

@ -2,6 +2,20 @@ Shindo.tests('Compute::VcloudDirector | task requests', ['vclouddirector']) do
@service = Fog::Compute::VcloudDirector.new
tests('error conditions') do
tests('retrieve non-existent TasksList').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.get_task_list('00000000-0000-0000-0000-000000000000')
end
tests('retrieve non-existent Task').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.get_task('00000000-0000-0000-0000-000000000000')
end
tests('cancel non-existent Task').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.post_cancel_task('00000000-0000-0000-0000-000000000000')
end
end
@org_id = VcloudDirector::Compute::Helper.current_org_id(@service)
tests('#get_task_list').data_matches_schema(VcloudDirector::Compute::Schema::TASKS_LIST_TYPE) do
session = @service.get_current_session.body
org_href = session[:Link].detect {|l| l[:type] == 'application/vnd.vmware.vcloud.org+xml'}[:href]
@ -9,12 +23,13 @@ Shindo.tests('Compute::VcloudDirector | task requests', ['vclouddirector']) do
@tasks_list = @service.get_task_list(@org_uuid).body
end
tests('retrieve non-existent TasksList').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.get_task_list('00000000-0000-0000-0000-000000000000')
end
tests('retrieve non-existent Task').raises(Fog::Compute::VcloudDirector::Forbidden) do
@service.get_task('00000000-0000-0000-0000-000000000000')
tests('each task in the task list') do
@tasks_list[:Task].each do |task|
task_id = task[:href].split('/').last
tests("#get_task(#{task_id}").data_matches_schema(VcloudDirector::Compute::Schema::TASK_TYPE) do
@service.get_task(task_id).body
end
end
end
end