зеркало из https://github.com/github/fog.git
Merge pull request #1505 from rupakg/update_hpfog_0.0.19_to_upstream_fog_1.9.0
Update hpfog 0.0.19 to upstream fog 1.9.0 (2)
This commit is contained in:
Коммит
23f3e94756
|
@ -10,7 +10,6 @@ Gem::Specification.new do |s|
|
|||
s.date = '2013-01-19'
|
||||
s.rubyforge_project = 'fog'
|
||||
|
||||
|
||||
## Make sure your summary is short. The description may be as long
|
||||
## as you like.
|
||||
s.summary = "brings clouds to you"
|
||||
|
|
|
@ -3,6 +3,8 @@ class HP < Fog::Bin
|
|||
|
||||
def class_for(key)
|
||||
case key
|
||||
when :block_storage
|
||||
Fog::HP::BlockStorage
|
||||
when :cdn
|
||||
Fog::CDN::HP
|
||||
when :compute
|
||||
|
@ -17,11 +19,16 @@ class HP < Fog::Bin
|
|||
def [](service)
|
||||
@@connections ||= Hash.new do |hash, key|
|
||||
hash[key] = case key
|
||||
when :block_storage
|
||||
Fog::HP::BlockStorage.new
|
||||
when :cdn
|
||||
Fog::Logger.warning("HP[:cdn] is deprecated, use CDN[:hp] instead")
|
||||
Fog::CDN.new(:provider => 'HP')
|
||||
when :compute
|
||||
Fog::Logger.warning("HP[:compute] is deprecated, use Compute[:hp] instead")
|
||||
Fog::Compute.new(:provider => 'HP')
|
||||
when :storage
|
||||
Fog::Logger.warning("HP[:storage] is deprecated, use Storage[:hp] instead")
|
||||
Fog::Storage.new(:provider => 'HP')
|
||||
else
|
||||
raise ArgumentError, "Unrecognized service: #{key.inspect}"
|
||||
|
|
|
@ -46,9 +46,10 @@ An alternate file may be used by placing its path in the FOG_RC environment vari
|
|||
:go_grid_shared_secret:
|
||||
:google_storage_access_key_id:
|
||||
:google_storage_secret_access_key:
|
||||
:hp_account_id:
|
||||
:hp_access_key:
|
||||
:hp_secret_key:
|
||||
:hp_tenant_id:
|
||||
:hp_avl_zone:
|
||||
:linode_api_key:
|
||||
:local_root:
|
||||
:bare_metal_cloud_password:
|
||||
|
|
|
@ -2,6 +2,12 @@ require 'fog/core'
|
|||
|
||||
module Fog
|
||||
module HP
|
||||
|
||||
# define a specific version for the HP Provider
|
||||
unless const_defined?(:VERSION)
|
||||
VERSION = '0.0.19'
|
||||
end
|
||||
|
||||
extend Fog::Provider
|
||||
|
||||
module Errors
|
||||
|
@ -13,10 +19,14 @@ module Fog
|
|||
data = nil
|
||||
message = nil
|
||||
else
|
||||
data = Fog::JSON.decode(error.response.body)
|
||||
message = data['message']
|
||||
if message.nil? and !data.values.first.nil?
|
||||
message = data.values.first['message']
|
||||
begin
|
||||
data = Fog::JSON.decode(error.response.body)
|
||||
message = data['message']
|
||||
if message.nil? and !data.values.first.nil?
|
||||
message = data.values.first['message']
|
||||
end
|
||||
rescue MultiJson::DecodeError
|
||||
message = error.response.body #### body is not in JSON format, so just return as is
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -29,6 +39,7 @@ module Fog
|
|||
class InternalServerError < ServiceError; end
|
||||
class Conflict < ServiceError; end
|
||||
class NotFound < ServiceError; end
|
||||
class Forbidden < ServiceError; end
|
||||
class ServiceUnavailable < ServiceError; end
|
||||
|
||||
class BadRequest < ServiceError
|
||||
|
@ -47,6 +58,7 @@ module Fog
|
|||
service(:cdn, 'hp/cdn', 'CDN')
|
||||
service(:compute, 'hp/compute', 'Compute')
|
||||
service(:storage, 'hp/storage', 'Storage')
|
||||
service(:block_storage, 'hp/block_storage', 'BlockStorage')
|
||||
|
||||
# legacy swauth 1.0/1.1 style authentication
|
||||
def self.authenticate_v1(options, connection_options = {})
|
||||
|
@ -61,14 +73,17 @@ module Fog
|
|||
@auth_path = "auth/v1.0"
|
||||
end
|
||||
service_url = "#{@scheme}://#{@host}:#{@port}"
|
||||
# Set the User-Agent
|
||||
@user_agent = options[:user_agent]
|
||||
set_user_agent_header(connection_options, "hpfog v1/#{Fog::HP::VERSION}", @user_agent)
|
||||
connection = Fog::Connection.new(service_url, false, connection_options)
|
||||
@hp_account_id = options[:hp_account_id]
|
||||
@hp_access_key = options[:hp_access_key]
|
||||
@hp_secret_key = options[:hp_secret_key]
|
||||
response = connection.request({
|
||||
:expects => [200, 204],
|
||||
:headers => {
|
||||
'X-Auth-Key' => @hp_secret_key,
|
||||
'X-Auth-User' => @hp_account_id
|
||||
'X-Auth-User' => @hp_access_key
|
||||
},
|
||||
:host => @host,
|
||||
:port => @port,
|
||||
|
@ -101,16 +116,19 @@ module Fog
|
|||
@auth_path = "v2.0/tokens"
|
||||
end
|
||||
service_url = "#{@scheme}://#{@host}:#{@port}"
|
||||
# Set the User-Agent. If the caller sets a user_agent, use it.
|
||||
@user_agent = options[:user_agent]
|
||||
set_user_agent_header(connection_options, "hpfog/#{Fog::HP::VERSION}", @user_agent)
|
||||
connection = Fog::Connection.new(service_url, false, connection_options)
|
||||
|
||||
### Implement HP Control Services Authentication services ###
|
||||
# Get the style of auth credentials passed, defaults to access/secret key style
|
||||
@hp_use_upass_auth_style = options[:hp_use_upass_auth_style] || false
|
||||
@hp_account_id = options[:hp_account_id]
|
||||
@hp_access_key = options[:hp_access_key]
|
||||
@hp_secret_key = options[:hp_secret_key]
|
||||
@hp_tenant_id = options[:hp_tenant_id]
|
||||
@hp_service_type = options[:hp_service_type]
|
||||
@hp_avl_zone = options[:hp_avl_zone] || :az1
|
||||
@hp_avl_zone = options[:hp_avl_zone]
|
||||
|
||||
### Decide which auth style to use
|
||||
unless (@hp_use_upass_auth_style)
|
||||
|
@ -118,7 +136,7 @@ module Fog
|
|||
request_body = {
|
||||
'auth' => {
|
||||
'apiAccessKeyCredentials' => {
|
||||
'accessKey' => "#{@hp_account_id}",
|
||||
'accessKey' => "#{@hp_access_key}",
|
||||
'secretKey' => "#{@hp_secret_key}"
|
||||
}
|
||||
}
|
||||
|
@ -128,17 +146,17 @@ module Fog
|
|||
request_body = {
|
||||
'auth' => {
|
||||
'passwordCredentials' => {
|
||||
'username' => "#{@hp_account_id}",
|
||||
'username' => "#{@hp_access_key}",
|
||||
'password' => "#{@hp_secret_key}"
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
# add tenant_id if specified
|
||||
request_body['auth']['tenantId'] = "#{@hp_tenant_id}" if @hp_tenant_id
|
||||
request_body['auth']['tenantId'] = @hp_tenant_id if @hp_tenant_id
|
||||
|
||||
### Make the call to CS to get auth token and service catalog
|
||||
response = service.request(
|
||||
response = connection.request(
|
||||
{
|
||||
:expects => 200,
|
||||
:headers => {
|
||||
|
@ -157,9 +175,9 @@ module Fog
|
|||
### fish out auth_token and endpoint for the service
|
||||
auth_token = body['access']['token']['id']
|
||||
endpoint_url = get_endpoint_from_catalog(body['access']['serviceCatalog'], @hp_service_type, @hp_avl_zone)
|
||||
# If service is Storage, then get the CDN endpoint as well
|
||||
if @hp_service_type == "object-store"
|
||||
cdn_endpoint_url = get_endpoint_from_catalog(body['access']['serviceCatalog'], "hpext:cdn", @hp_avl_zone)
|
||||
# If service is Storage, then get the CDN endpoint as well. 'Name' is unique instead of 'Type'
|
||||
if @hp_service_type == "Object Storage"
|
||||
cdn_endpoint_url = get_endpoint_from_catalog(body['access']['serviceCatalog'], "CDN", @hp_avl_zone)
|
||||
end
|
||||
|
||||
return {
|
||||
|
@ -180,19 +198,31 @@ module Fog
|
|||
private
|
||||
|
||||
def self.get_endpoint_from_catalog(service_catalog, service_type, avl_zone)
|
||||
if service_catalog
|
||||
service_item = service_catalog.select {|s| s["type"] == service_type}.first
|
||||
if service_item and service_item['endpoints'] and
|
||||
if avl_zone == :az1
|
||||
endpoint_url = service_item['endpoints'][0]['publicURL'] if service_item['endpoints'][0]
|
||||
elsif avl_zone == :az2
|
||||
endpoint_url = service_item['endpoints'][1]['publicURL'] if service_item['endpoints'][1]
|
||||
end
|
||||
raise "Unable to retrieve endpoint service url from service catalog." if endpoint_url.nil?
|
||||
return endpoint_url
|
||||
raise "Unable to parse service catalog." unless service_catalog
|
||||
service_item = service_catalog.detect do |s|
|
||||
# 'Name' is unique instead of 'Type'
|
||||
s["name"] == service_type
|
||||
end
|
||||
if service_item and service_item['endpoints']
|
||||
endpoint = service_item['endpoints'].detect do |ep|
|
||||
ep['region'] == avl_zone
|
||||
end
|
||||
endpoint_url = endpoint['publicURL'] if endpoint
|
||||
raise "Unable to retrieve endpoint service url for availability zone '#{avl_zone}' from service catalog. " if endpoint_url.nil?
|
||||
return endpoint_url
|
||||
end
|
||||
end
|
||||
|
||||
def self.set_user_agent_header(conn_opts, base_str, client_str)
|
||||
if client_str
|
||||
user_agent = {'User-Agent' => base_str + " (#{client_str})"}
|
||||
else
|
||||
raise "Unable to parse service catalog."
|
||||
user_agent = {'User-Agent' => base_str}
|
||||
end
|
||||
if conn_opts[:headers]
|
||||
conn_opts[:headers] = user_agent.merge!(conn_opts[:headers])
|
||||
else
|
||||
conn_opts[:headers] = user_agent
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
0.0.19 18/01/2013
|
||||
=================
|
||||
- update Block Storage namespace to be Fog::HP::BlockStorage
|
||||
- merge with upstream fog v1.8.0
|
||||
- deprecate hp_account_id to use hp_access_key instead
|
||||
|
||||
0.0.18 12/04/2012
|
||||
=================
|
||||
- add support for controlled access via cross-tenant ACLs
|
||||
- add support for creating bootable volumes
|
||||
- add support for creating persistent server instances using bootable volumes
|
||||
|
||||
0.0.17 10/16/2012
|
||||
=================
|
||||
- add support for generating temporary urls
|
||||
- add support for retrieving encrypted password for Windows instances
|
||||
- add support for creating Windows instances
|
||||
|
||||
0.0.16 08/15/2012
|
||||
=================
|
||||
- add support for User-Agent string in header
|
||||
- add support for Snapshots API to BlockStorage provider
|
||||
- add support for Volumes API to BlockStorage provider
|
||||
- add BlockStorage service to HP provider
|
||||
- upgrade to excon 0.14.0 to take advantage of instrumentation
|
||||
- add a head method for the directories collection
|
||||
- update image model
|
||||
- update put_object and get_object to accept blocks
|
||||
|
||||
0.0.15 06/08/2012
|
||||
=================
|
||||
- add metadata attribute in server and image models to manage metadata
|
||||
- add metadata model and request layer functionality with mocking support
|
||||
- add tests for metadata
|
||||
- upgrade to excon 0.13.0 to take advantage of ssl passthru functionality
|
||||
- add security_groups attribute to the server model
|
||||
- add support for future availability zones for all HP services
|
||||
- change hp_avl_zone to be a required parameter for all HP services
|
||||
- add support for console output in compute service
|
||||
- add helper method for cdn public ssl url
|
||||
- add tests for storage, compute and cdn services
|
||||
- improve quality of mocks to match real implementation
|
||||
|
||||
0.0.14 02/23/2012
|
||||
=================
|
||||
- minor fix for public ip address
|
||||
- minor fix for exceptions raised by CDN service
|
||||
- add keypair get/set methods to server model
|
||||
|
||||
0.0.13 02/09/2012
|
||||
=================
|
||||
- provide access to availability zones for compute
|
||||
- minor fix for CS authentication uri
|
||||
- update inline documentation
|
||||
- update README_HP with copyright message
|
||||
|
||||
0.0.12 02/02/2012
|
||||
=================
|
||||
- integrate CS authentication
|
||||
- refactor HP provider to work with legacy v1 authentication as well
|
||||
- integrate CDN to work with Storage provider
|
||||
- add additional attributes for CDN provider
|
||||
- remove bits and add cores as alias to vcpus in flavor model
|
||||
- update inline documentation
|
||||
- update README_HP with copyright message
|
||||
|
||||
0.0.11 01/09/2012
|
||||
=================
|
||||
- add ability to customize various connection timeouts options
|
||||
- add CDN service capabilities
|
||||
- integrate the CDN service with the Storage service
|
||||
- add a new CDN Uri option to Storage service
|
||||
- incorporate Diablo 4 API changes
|
||||
- update image, server and flavor models
|
||||
- update create_image and create_server calls
|
||||
- add rebuild_server and change_password_server calls
|
||||
- new extensions APIs
|
||||
- add keypair model and request layer with mocking support
|
||||
- add security group model and request layer with mocking support
|
||||
- add security group rule model and request layer with mocking support
|
||||
- add address model and request layer with mocking support
|
||||
- update server model with address management methods
|
||||
- update server creation to use keypairs, security groups and other options
|
||||
- update inline documentation
|
||||
|
||||
0.0.10 10/18/2011
|
||||
=================
|
||||
- merge with upstream fog v1.0.0
|
||||
|
||||
0.0.9 09/21/2011
|
||||
================
|
||||
- minor bug fixes
|
||||
- add support for special char. including '?' in container and object names
|
||||
- fix public_url for special char. in container and object names
|
||||
|
||||
0.0.8 08/29/2011
|
||||
================
|
||||
- add README_HP.rdoc
|
||||
- add CHANGELOG.hp
|
||||
- remove resize_server, confirm_resized_server and revert_resized_server from HP Cloud Compute
|
||||
|
||||
0.0.7 08/10/2011
|
||||
================
|
||||
- minor fixes
|
||||
- added acl support to directory
|
||||
- added public? method to directory model
|
||||
- added mock support for HP Cloud Object Storage
|
||||
|
||||
0.0.6 07/26/2011
|
||||
================
|
||||
- initial release with name change to 'hpfog'
|
||||
- HP provider for HP Cloud Object Storage
|
||||
- HP provider for HP Cloud Compute
|
|
@ -29,11 +29,14 @@ If you should ever need to remove the library:
|
|||
The Ruby Fog library is well documented on the community web site at {fog.io}[http://fog.io], but for specific examples
|
||||
using HP's extensions, see:
|
||||
|
||||
* {HP Cloud Fog library - Object Storage Examples}[https://build.hpcloud.com/bindings/fog/object-storage]
|
||||
* {HP Cloud Fog library - Compute Examples}[https://build.hpcloud.com/bindings/fog/compute]
|
||||
* {HP Cloud Fog library - CDN Examples}[https://build.hpcloud.com/bindings/fog/cdn]
|
||||
* {HP Cloud Fog library - Object Storage Examples}[https://docs.hpcloud.com/bindings/fog/object-storage]
|
||||
* {HP Cloud Fog library - Compute Examples}[https://docs.hpcloud.com/bindings/fog/compute]
|
||||
* {HP Cloud Fog library - CDN Examples}[https://docs.hpcloud.com/bindings/fog/cdn]
|
||||
* {HP Cloud Fog library - Block Storage Examples}[https://docs.hpcloud.com/bindings/fog/block-storage]
|
||||
|
||||
Having trouble? Get help over at the {Forums}[https://community.hpcloud.com/forum] or
|
||||
at the {Knowledge Base}[https://community.hpcloud.com/knowledge-base] areas.
|
||||
|
||||
Having trouble? {Get help over at the Forums}[https://connect.hpcloud.com]
|
||||
|
||||
== Notice
|
||||
|
||||
|
@ -56,5 +59,3 @@ PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
require 'fog/hp'
|
||||
|
||||
module Fog
|
||||
module HP
|
||||
class BlockStorage < Fog::Service
|
||||
|
||||
requires :hp_secret_key, :hp_tenant_id, :hp_avl_zone
|
||||
recognizes :hp_auth_uri
|
||||
recognizes :persistent, :connection_options
|
||||
recognizes :hp_use_upass_auth_style, :hp_auth_version, :user_agent
|
||||
recognizes :hp_access_key, :hp_account_id # :hp_account_id is deprecated use hp_access_key instead
|
||||
|
||||
secrets :hp_secret_key
|
||||
|
||||
model_path 'fog/hp/models/block_storage'
|
||||
model :volume
|
||||
collection :volumes
|
||||
collection :bootable_volumes
|
||||
|
||||
model :snapshot
|
||||
collection :snapshots
|
||||
|
||||
request_path 'fog/hp/requests/block_storage'
|
||||
request :create_volume
|
||||
request :delete_volume
|
||||
request :get_bootable_volume_details
|
||||
request :get_volume_details
|
||||
request :list_bootable_volumes
|
||||
request :list_volumes
|
||||
|
||||
request :create_snapshot
|
||||
request :delete_snapshot
|
||||
request :get_snapshot_details
|
||||
request :list_snapshots
|
||||
|
||||
module Utils
|
||||
|
||||
def compute
|
||||
@compute ||= Fog::Compute.new(
|
||||
:provider => 'HP',
|
||||
:hp_access_key => @hp_access_key,
|
||||
:hp_secret_key => @hp_secret_key,
|
||||
:hp_auth_uri => @hp_auth_uri,
|
||||
:hp_tenant_id => @hp_tenant_id,
|
||||
:hp_avl_zone => @hp_avl_zone,
|
||||
:connection_options => @connection_options
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock
|
||||
include Utils
|
||||
|
||||
def self.data
|
||||
@data ||= Hash.new do |hash, key|
|
||||
hash[key] = {
|
||||
:volumes => {},
|
||||
:snapshots => {}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def self.reset
|
||||
@data = nil
|
||||
end
|
||||
|
||||
def initialize(options={})
|
||||
# deprecate hp_account_id
|
||||
if options[:hp_account_id]
|
||||
Fog::Logger.deprecation(":hp_account_id is deprecated, please use :hp_access_key instead.")
|
||||
@hp_access_key = options.delete(:hp_account_id)
|
||||
end
|
||||
@hp_access_key = options[:hp_access_key]
|
||||
unless @hp_access_key
|
||||
raise ArgumentError.new("Missing required arguments: hp_access_key. :hp_account_id is deprecated, please use :hp_access_key instead.")
|
||||
end
|
||||
end
|
||||
|
||||
def data
|
||||
self.class.data[@hp_access_key]
|
||||
end
|
||||
|
||||
def reset_data
|
||||
self.class.data.delete(@hp_access_key)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Real
|
||||
include Utils
|
||||
|
||||
def initialize(options={})
|
||||
# deprecate hp_account_id
|
||||
if options[:hp_account_id]
|
||||
Fog::Logger.deprecation(":hp_account_id is deprecated, please use :hp_access_key instead.")
|
||||
options[:hp_access_key] = options.delete(:hp_account_id)
|
||||
end
|
||||
@hp_access_key = options[:hp_access_key]
|
||||
unless @hp_access_key
|
||||
raise ArgumentError.new("Missing required arguments: hp_access_key. :hp_account_id is deprecated, please use :hp_access_key instead.")
|
||||
end
|
||||
@hp_secret_key = options[:hp_secret_key]
|
||||
@hp_auth_uri = options[:hp_auth_uri]
|
||||
@connection_options = options[:connection_options] || {}
|
||||
### Set an option to use the style of authentication desired; :v1 or :v2 (default)
|
||||
auth_version = options[:hp_auth_version] || :v2
|
||||
### Pass the service name for object storage to the authentication call
|
||||
options[:hp_service_type] = "Block Storage"
|
||||
@hp_tenant_id = options[:hp_tenant_id]
|
||||
@hp_avl_zone = options[:hp_avl_zone]
|
||||
|
||||
### Make the authentication call
|
||||
if (auth_version == :v2)
|
||||
# Call the control services authentication
|
||||
credentials = Fog::HP.authenticate_v2(options, @connection_options)
|
||||
# the CS service catalog returns the block storage endpoint
|
||||
@hp_block_uri = credentials[:endpoint_url]
|
||||
else
|
||||
# Call the legacy v1.0/v1.1 authentication
|
||||
credentials = Fog::HP.authenticate_v1(options, @connection_options)
|
||||
# the user sends in the block storage endpoint
|
||||
@hp_block_uri = options[:hp_auth_uri]
|
||||
end
|
||||
|
||||
@auth_token = credentials[:auth_token]
|
||||
@persistent = options[:persistent] || false
|
||||
|
||||
uri = URI.parse(@hp_block_uri)
|
||||
@host = uri.host
|
||||
@path = uri.path
|
||||
@port = uri.port
|
||||
@scheme = uri.scheme
|
||||
|
||||
@connection = Fog::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
|
||||
end
|
||||
|
||||
def reload
|
||||
@connection.reset
|
||||
end
|
||||
|
||||
def request(params, parse_json = true, &block)
|
||||
begin
|
||||
response = @connection.request(params.merge!({
|
||||
:headers => {
|
||||
'Content-Type' => 'application/json',
|
||||
'X-Auth-Token' => @auth_token
|
||||
}.merge!(params[:headers] || {}),
|
||||
:host => @host,
|
||||
:path => "#{@path}/#{params[:path]}",
|
||||
}), &block)
|
||||
rescue Excon::Errors::HTTPStatusError => error
|
||||
raise case error
|
||||
when Excon::Errors::NotFound
|
||||
Fog::HP::BlockStorage::NotFound.slurp(error)
|
||||
else
|
||||
error
|
||||
end
|
||||
end
|
||||
if !response.body.empty? && parse_json && response.headers['Content-Type'] =~ %r{application/json}
|
||||
response.body = Fog::JSON.decode(response.body)
|
||||
end
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5,8 +5,11 @@ module Fog
|
|||
module CDN
|
||||
class HP < Fog::Service
|
||||
|
||||
requires :hp_secret_key, :hp_account_id, :hp_tenant_id
|
||||
recognizes :hp_auth_uri, :hp_cdn_uri, :persistent, :connection_options, :hp_use_upass_auth_style, :hp_auth_version
|
||||
requires :hp_secret_key, :hp_tenant_id, :hp_avl_zone
|
||||
recognizes :hp_auth_uri, :hp_cdn_uri
|
||||
recognizes :hp_use_upass_auth_style, :hp_auth_version, :user_agent
|
||||
recognizes :persistent, :connection_options
|
||||
recognizes :hp_access_key, :hp_account_id # :hp_account_id is deprecated use hp_access_key instead
|
||||
|
||||
secrets :hp_secret_key
|
||||
|
||||
|
@ -39,15 +42,23 @@ module Fog
|
|||
end
|
||||
|
||||
def initialize(options={})
|
||||
@hp_account_id = options[:hp_account_id]
|
||||
# deprecate hp_account_id
|
||||
if options[:hp_account_id]
|
||||
Fog::Logger.deprecation(":hp_account_id is deprecated, please use :hp_access_key instead.")
|
||||
@hp_access_key = options.delete(:hp_account_id)
|
||||
end
|
||||
@hp_access_key = options[:hp_access_key]
|
||||
unless @hp_access_key
|
||||
raise ArgumentError.new("Missing required arguments: hp_access_key. :hp_account_id is deprecated, please use :hp_access_key instead.")
|
||||
end
|
||||
end
|
||||
|
||||
def data
|
||||
self.class.data[@hp_account_id]
|
||||
self.class.data[@hp_access_key]
|
||||
end
|
||||
|
||||
def reset_data
|
||||
self.class.data.delete(@hp_account_id)
|
||||
self.class.data.delete(@hp_access_key)
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -56,11 +67,22 @@ module Fog
|
|||
include Utils
|
||||
|
||||
def initialize(options={})
|
||||
# deprecate hp_account_id
|
||||
if options[:hp_account_id]
|
||||
Fog::Logger.deprecation(":hp_account_id is deprecated, please use :hp_access_key instead.")
|
||||
options[:hp_access_key] = options.delete(:hp_account_id)
|
||||
end
|
||||
@hp_access_key = options[:hp_access_key]
|
||||
unless @hp_access_key
|
||||
raise ArgumentError.new("Missing required arguments: hp_access_key. :hp_account_id is deprecated, please use :hp_access_key instead.")
|
||||
end
|
||||
@hp_secret_key = options[:hp_secret_key]
|
||||
@connection_options = options[:connection_options] || {}
|
||||
### Set an option to use the style of authentication desired; :v1 or :v2 (default)
|
||||
auth_version = options[:hp_auth_version] || :v2
|
||||
### Pass the service type for object storage to the authentication call
|
||||
options[:hp_service_type] = "hpext:cdn"
|
||||
### Pass the service name for object storage to the authentication call
|
||||
options[:hp_service_type] = "CDN"
|
||||
@hp_tenant_id = options[:hp_tenant_id]
|
||||
|
||||
### Make the authentication call
|
||||
if (auth_version == :v2)
|
||||
|
|
|
@ -5,8 +5,11 @@ module Fog
|
|||
module Compute
|
||||
class HP < Fog::Service
|
||||
|
||||
requires :hp_secret_key, :hp_account_id, :hp_tenant_id
|
||||
recognizes :hp_auth_uri, :hp_servicenet, :persistent, :connection_options, :hp_use_upass_auth_style, :hp_auth_version, :hp_avl_zone
|
||||
requires :hp_secret_key, :hp_tenant_id, :hp_avl_zone
|
||||
recognizes :hp_auth_uri
|
||||
recognizes :hp_use_upass_auth_style, :hp_auth_version, :user_agent
|
||||
recognizes :persistent, :connection_options
|
||||
recognizes :hp_access_key, :hp_account_id # :hp_account_id is deprecated use hp_access_key instead
|
||||
|
||||
secrets :hp_secret_key
|
||||
|
||||
|
@ -19,6 +22,8 @@ module Fog
|
|||
collection :images
|
||||
model :key_pair
|
||||
collection :key_pairs
|
||||
model :meta
|
||||
collection :metadata
|
||||
model :security_group
|
||||
collection :security_groups
|
||||
model :server
|
||||
|
@ -27,6 +32,7 @@ module Fog
|
|||
request_path 'fog/hp/requests/compute'
|
||||
request :allocate_address
|
||||
request :associate_address
|
||||
request :attach_volume
|
||||
request :change_password_server
|
||||
#request :confirm_resized_server
|
||||
request :create_image
|
||||
|
@ -34,15 +40,21 @@ module Fog
|
|||
request :create_security_group
|
||||
request :create_security_group_rule
|
||||
request :create_server
|
||||
request :create_persistent_server
|
||||
request :delete_image
|
||||
request :delete_key_pair
|
||||
request :delete_meta
|
||||
request :delete_security_group
|
||||
request :delete_security_group_rule
|
||||
request :delete_server
|
||||
request :detach_volume
|
||||
request :disassociate_address
|
||||
request :get_address
|
||||
request :get_console_output
|
||||
request :get_flavor_details
|
||||
request :get_image_details
|
||||
request :get_meta
|
||||
request :get_windows_password
|
||||
request :get_security_group
|
||||
request :get_server_details
|
||||
request :list_addresses
|
||||
|
@ -51,10 +63,12 @@ module Fog
|
|||
request :list_images
|
||||
request :list_images_detail
|
||||
request :list_key_pairs
|
||||
request :list_metadata
|
||||
request :list_security_groups
|
||||
request :list_server_addresses
|
||||
request :list_server_private_addresses
|
||||
request :list_server_public_addresses
|
||||
request :list_server_volumes
|
||||
request :list_servers
|
||||
request :list_servers_detail
|
||||
request :reboot_server
|
||||
|
@ -63,9 +77,55 @@ module Fog
|
|||
#request :resize_server
|
||||
#request :revert_resized_server
|
||||
request :server_action
|
||||
request :set_metadata
|
||||
request :update_meta
|
||||
request :update_metadata
|
||||
request :update_server
|
||||
|
||||
module Utils
|
||||
|
||||
# extract windows password from log
|
||||
def extract_password_from_log(log_text)
|
||||
encrypted_text = ""
|
||||
section = []
|
||||
return if log_text.nil?
|
||||
log_text.each_line do |line|
|
||||
case line
|
||||
when /^-----BEGIN (\w+)/
|
||||
section.push $1
|
||||
next
|
||||
when /^-----END (\w+)/
|
||||
section.pop
|
||||
next
|
||||
end
|
||||
|
||||
case section
|
||||
when ["BASE64"]
|
||||
encrypted_text << line
|
||||
end
|
||||
end
|
||||
# return the encrypted portion only
|
||||
encrypted_text
|
||||
end
|
||||
|
||||
def encrypt_using_public_key(text, public_key_data)
|
||||
return if (text.nil? || public_key_data.nil?)
|
||||
public_key = OpenSSL::PKey::RSA.new(public_key_data)
|
||||
encrypted_text = public_key.public_encrypt(text).strip
|
||||
Base64.encode64(encrypted_text)
|
||||
end
|
||||
|
||||
def decrypt_using_private_key(encrypted_text, private_key_data)
|
||||
return if (encrypted_text.nil? || private_key_data.nil?)
|
||||
private_key = OpenSSL::PKey::RSA.new(private_key_data)
|
||||
from_base64 = Base64.decode64(encrypted_text)
|
||||
private_key.private_decrypt(from_base64).strip
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock
|
||||
include Utils
|
||||
|
||||
def self.data
|
||||
@data ||= Hash.new do |hash, key|
|
||||
|
@ -91,30 +151,46 @@ module Fog
|
|||
end
|
||||
|
||||
def initialize(options={})
|
||||
@hp_account_id = options[:hp_account_id]
|
||||
# deprecate hp_account_id
|
||||
if options[:hp_account_id]
|
||||
Fog::Logger.deprecation(":hp_account_id is deprecated, please use :hp_access_key instead.")
|
||||
@hp_access_key = options.delete(:hp_account_id)
|
||||
end
|
||||
@hp_access_key = options[:hp_access_key]
|
||||
unless @hp_access_key
|
||||
raise ArgumentError.new("Missing required arguments: hp_access_key. :hp_account_id is deprecated, please use :hp_access_key instead.")
|
||||
end
|
||||
end
|
||||
|
||||
def data
|
||||
self.class.data[@hp_account_id]
|
||||
self.class.data[@hp_access_key]
|
||||
end
|
||||
|
||||
def reset_data
|
||||
self.class.data.delete(@hp_account_id)
|
||||
self.class.data.delete(@hp_access_key)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Real
|
||||
include Utils
|
||||
|
||||
def initialize(options={})
|
||||
# deprecate hp_account_id
|
||||
if options[:hp_account_id]
|
||||
Fog::Logger.deprecation(":hp_account_id is deprecated, please use :hp_access_key instead.")
|
||||
options[:hp_access_key] = options.delete(:hp_account_id)
|
||||
end
|
||||
@hp_access_key = options[:hp_access_key]
|
||||
unless @hp_access_key
|
||||
raise ArgumentError.new("Missing required arguments: hp_access_key. :hp_account_id is deprecated, please use :hp_access_key instead.")
|
||||
end
|
||||
@hp_secret_key = options[:hp_secret_key]
|
||||
@hp_account_id = options[:hp_account_id]
|
||||
@hp_servicenet = options[:hp_servicenet]
|
||||
@connection_options = options[:connection_options] || {}
|
||||
### Set an option to use the style of authentication desired; :v1 or :v2 (default)
|
||||
auth_version = options[:hp_auth_version] || :v2
|
||||
### Pass the service type for compute via the options hash
|
||||
options[:hp_service_type] = "compute"
|
||||
### Pass the service name for compute via the options hash
|
||||
options[:hp_service_type] = "Compute"
|
||||
@hp_tenant_id = options[:hp_tenant_id]
|
||||
|
||||
### Make the authentication call
|
||||
|
@ -133,12 +209,11 @@ module Fog
|
|||
@auth_token = credentials[:auth_token]
|
||||
|
||||
uri = URI.parse(@hp_compute_uri)
|
||||
@host = @hp_servicenet == true ? "snet-#{uri.host}" : uri.host
|
||||
@host = uri.host
|
||||
@path = uri.path
|
||||
@persistent = options[:persistent] || false
|
||||
@port = uri.port
|
||||
@scheme = uri.scheme
|
||||
Excon.ssl_verify_peer = false if options[:hp_servicenet] == true
|
||||
|
||||
@connection = Fog::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
|
||||
end
|
||||
|
@ -166,12 +241,8 @@ module Fog
|
|||
error
|
||||
end
|
||||
end
|
||||
unless response.body.empty?
|
||||
begin
|
||||
response.body = Fog::JSON.decode(response.body)
|
||||
rescue MultiJson::DecodeError => error
|
||||
response.body #### the body is not in JSON format so just return it as it is
|
||||
end
|
||||
if !response.body.empty? && parse_json && response.headers['Content-Type'] =~ %r{application/json}
|
||||
response.body = Fog::JSON.decode(response.body)
|
||||
end
|
||||
response
|
||||
end
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/hp/models/block_storage/volume'
|
||||
|
||||
module Fog
|
||||
module HP
|
||||
class BlockStorage
|
||||
|
||||
class BootableVolumes < Fog::Collection
|
||||
|
||||
model Fog::HP::BlockStorage::Volume
|
||||
|
||||
def all
|
||||
data = service.list_bootable_volumes.body['volumes']
|
||||
load(data)
|
||||
end
|
||||
|
||||
def get(volume_id)
|
||||
volume = service.get_bootable_volume_details(volume_id).body['volume']
|
||||
new(volume)
|
||||
rescue Fog::HP::BlockStorage::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,56 @@
|
|||
require 'fog/core/model'
|
||||
|
||||
module Fog
|
||||
module HP
|
||||
class BlockStorage
|
||||
|
||||
class Snapshot < Fog::Model
|
||||
|
||||
identity :id
|
||||
|
||||
attribute :name, :aliases => 'displayName'
|
||||
attribute :description, :aliases => 'displayDescription'
|
||||
attribute :size
|
||||
attribute :status
|
||||
attribute :created_at, :aliases => 'createdAt'
|
||||
attribute :volume_id, :aliases => 'volumeId'
|
||||
#attribute :metadata
|
||||
|
||||
def initialize(attributes = {})
|
||||
# assign these attributes first to prevent race condition with persisted?
|
||||
self.force = attributes.delete(:force) # force snapshotting of attached volumes
|
||||
super
|
||||
end
|
||||
|
||||
def destroy
|
||||
requires :id
|
||||
service.delete_snapshot(id)
|
||||
true
|
||||
end
|
||||
|
||||
def force=(new_force)
|
||||
@force = new_force
|
||||
end
|
||||
|
||||
def ready?
|
||||
self.status == 'available'
|
||||
end
|
||||
|
||||
def save
|
||||
raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if persisted?
|
||||
requires :name, :volume_id
|
||||
options = {
|
||||
#'metadata' => metadata, # TODO: Add metadata when snapshots support it
|
||||
'force' => @force
|
||||
}
|
||||
options = options.reject {|key, value| value.nil?}
|
||||
data = service.create_snapshot(name, description, volume_id, options)
|
||||
merge_attributes(data.body['snapshot'])
|
||||
true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,29 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/hp/models/block_storage/snapshot'
|
||||
|
||||
module Fog
|
||||
module HP
|
||||
class BlockStorage
|
||||
|
||||
class Snapshots < Fog::Collection
|
||||
|
||||
model Fog::HP::BlockStorage::Snapshot
|
||||
|
||||
def all
|
||||
data = service.list_snapshots.body['snapshots']
|
||||
load(data)
|
||||
end
|
||||
|
||||
def get(snapshot_id)
|
||||
if snapshot = service.get_snapshot_details(snapshot_id).body['snapshot']
|
||||
new(snapshot)
|
||||
end
|
||||
rescue Fog::HP::BlockStorage::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,102 @@
|
|||
require 'fog/core/model'
|
||||
|
||||
module Fog
|
||||
module HP
|
||||
class BlockStorage
|
||||
|
||||
class Volume < Fog::Model
|
||||
|
||||
identity :id
|
||||
|
||||
attribute :name, :aliases => 'displayName'
|
||||
attribute :description, :aliases => 'displayDescription'
|
||||
attribute :size
|
||||
attribute :status
|
||||
attribute :type, :aliases => 'volumeType'
|
||||
attribute :created_at, :aliases => 'createdAt'
|
||||
attribute :availability_zone, :aliases => 'availabilityZone'
|
||||
attribute :snapshot_id, :aliases => 'snapshotId'
|
||||
attribute :source_image_id, :aliases => 'sourceImageRef' # only for bootable volumes
|
||||
attribute :attachments
|
||||
attribute :metadata
|
||||
|
||||
attr_reader :server_id
|
||||
attr_reader :device
|
||||
|
||||
def initialize(attributes = {})
|
||||
# assign these attributes first to prevent race condition with new_record?
|
||||
self.image_id = attributes.delete(:image_id)
|
||||
super
|
||||
end
|
||||
|
||||
def device
|
||||
attachments[0]['device'] if has_attachments?
|
||||
end
|
||||
|
||||
def server_id
|
||||
attachments[0]['serverId'] if has_attachments?
|
||||
end
|
||||
|
||||
# used for creating bootable volumes
|
||||
def image_id=(new_image_id)
|
||||
@image_id = new_image_id
|
||||
end
|
||||
|
||||
# a volume can be attached to only one server at a time
|
||||
def has_attachments?
|
||||
!(attachments.nil? || attachments.empty? || attachments[0].empty?)
|
||||
end
|
||||
|
||||
def in_use?
|
||||
self.status == 'in-use'
|
||||
end
|
||||
|
||||
def ready?
|
||||
self.status == 'available'
|
||||
end
|
||||
|
||||
# volume can be attached to only one server at a time
|
||||
def attach(new_server_id, device)
|
||||
requires :id
|
||||
unless in_use?
|
||||
data = service.compute.attach_volume(new_server_id, id, device)
|
||||
merge_attributes(:attachments => attachments << data.body['volumeAttachment'])
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def detach
|
||||
requires :id
|
||||
if has_attachments?
|
||||
service.compute.detach_volume(server_id, id)
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def destroy
|
||||
requires :id
|
||||
service.delete_volume(id)
|
||||
true
|
||||
end
|
||||
|
||||
def save
|
||||
raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if persisted?
|
||||
requires :name, :size
|
||||
options = {
|
||||
'metadata' => metadata,
|
||||
'snapshot_id' => snapshot_id,
|
||||
'imageRef' => @image_id
|
||||
}
|
||||
options = options.reject {|key, value| value.nil?}
|
||||
data = service.create_volume(name, description, size, options)
|
||||
merge_attributes(data.body['volume'])
|
||||
true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,28 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/hp/models/block_storage/volume'
|
||||
|
||||
module Fog
|
||||
module HP
|
||||
class BlockStorage
|
||||
|
||||
class Volumes < Fog::Collection
|
||||
|
||||
model Fog::HP::BlockStorage::Volume
|
||||
|
||||
def all
|
||||
data = service.list_volumes.body['volumes']
|
||||
load(data)
|
||||
end
|
||||
|
||||
def get(volume_id)
|
||||
volume = service.get_volume_details(volume_id).body['volume']
|
||||
new(volume)
|
||||
rescue Fog::HP::BlockStorage::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -20,7 +20,6 @@ module Fog
|
|||
|
||||
def destroy
|
||||
requires :id
|
||||
|
||||
service.release_address(id)
|
||||
true
|
||||
end
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require 'fog/core/model'
|
||||
require 'fog/openstack/models/compute/metadata'
|
||||
|
||||
module Fog
|
||||
module Compute
|
||||
|
@ -13,15 +14,53 @@ module Fog
|
|||
attribute :updated_at, :aliases => 'updated'
|
||||
attribute :progress
|
||||
attribute :status
|
||||
attribute :minDisk, :aliases => 'min_disk'
|
||||
attribute :minRam, :aliases => 'min_ram'
|
||||
attribute :server, :aliases => 'server'
|
||||
attribute :server
|
||||
attribute :metadata
|
||||
attribute :links
|
||||
|
||||
# these values are extracted from metadata
|
||||
attr_reader :min_disk
|
||||
attr_reader :min_ram
|
||||
attr_reader :image_type
|
||||
attr_reader :architecture
|
||||
|
||||
def metadata
|
||||
@metadata ||= begin
|
||||
Fog::Compute::HP::Metadata.new({
|
||||
:service => service,
|
||||
:parent => self
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
def metadata=(new_metadata={})
|
||||
metas = []
|
||||
new_metadata.each_pair {|k,v| metas << {"key" => k, "value" => v} }
|
||||
metadata.load(metas)
|
||||
end
|
||||
|
||||
def min_disk
|
||||
m = metadata.get("min_disk")
|
||||
m.value unless m.nil?
|
||||
end
|
||||
|
||||
def min_ram
|
||||
m = metadata.get("min_ram")
|
||||
m.value unless m.nil?
|
||||
end
|
||||
|
||||
def image_type
|
||||
m = metadata.get("image_type")
|
||||
m.value unless m.nil?
|
||||
end
|
||||
|
||||
def architecture
|
||||
m = metadata.get("architecture")
|
||||
m.value unless m.nil?
|
||||
end
|
||||
|
||||
def destroy
|
||||
requires :id
|
||||
|
||||
service.delete_image(id)
|
||||
true
|
||||
end
|
||||
|
|
|
@ -9,14 +9,9 @@ module Fog
|
|||
|
||||
model Fog::Compute::HP::Image
|
||||
|
||||
attribute :server
|
||||
|
||||
def all
|
||||
data = service.list_images_detail.body['images']
|
||||
load(data)
|
||||
if server
|
||||
self.replace(self.select {|image| image.server.id == server.id})
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
|
|
|
@ -13,18 +13,14 @@ module Fog
|
|||
attribute :private_key
|
||||
attribute :user_id
|
||||
|
||||
attr_accessor :public_key
|
||||
|
||||
def destroy
|
||||
requires :name
|
||||
|
||||
service.delete_key_pair(name)
|
||||
true
|
||||
end
|
||||
|
||||
def save
|
||||
requires :name
|
||||
|
||||
data = if public_key
|
||||
service.create_key_pair(name, public_key).body['keypair']
|
||||
else
|
||||
|
@ -36,7 +32,6 @@ module Fog
|
|||
end
|
||||
|
||||
def write(path="#{ENV['HOME']}/.ssh/hp_#{Fog.credential.to_s}_#{name}.pem")
|
||||
|
||||
if writable?
|
||||
split_private_key = private_key.split(/\n/)
|
||||
File.open(path, "w") do |f|
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
require 'fog/core/model'
|
||||
require 'fog/hp/models/meta_parent'
|
||||
|
||||
module Fog
|
||||
module Compute
|
||||
class HP
|
||||
class Meta < Fog::Model
|
||||
|
||||
include Fog::Compute::HP::MetaParent
|
||||
|
||||
identity :key
|
||||
attribute :value
|
||||
|
||||
def destroy
|
||||
requires :identity
|
||||
service.delete_meta(collection_name, @parent.id, key)
|
||||
true
|
||||
end
|
||||
|
||||
def save
|
||||
requires :identity, :value
|
||||
service.update_meta(collection_name, @parent.id, key, value)
|
||||
true
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,79 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/hp/models/meta_parent'
|
||||
require 'fog/hp/models/compute/meta'
|
||||
require 'fog/hp/models/compute/image'
|
||||
require 'fog/hp/models/compute/server'
|
||||
|
||||
module Fog
|
||||
module Compute
|
||||
class HP
|
||||
|
||||
class Metadata < Fog::Collection
|
||||
|
||||
model Fog::Compute::HP::Meta
|
||||
|
||||
include Fog::Compute::HP::MetaParent
|
||||
|
||||
def all
|
||||
requires :parent
|
||||
if @parent.id
|
||||
metadata = service.list_metadata(collection_name, @parent.id).body['metadata']
|
||||
metas = []
|
||||
metadata.each_pair {|k,v| metas << {"key" => k, "value" => v} }
|
||||
load(metas)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy(key)
|
||||
requires :parent
|
||||
service.delete_meta(collection_name, @parent.id, key)
|
||||
rescue Fog::Compute::HP::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
def get(key)
|
||||
requires :parent
|
||||
data = service.get_meta(collection_name, @parent.id, key).body["meta"]
|
||||
metas = []
|
||||
data.each_pair {|k,v| metas << {"key" => k, "value" => v} }
|
||||
new(metas[0])
|
||||
rescue Fog::Compute::HP::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
def new(attributes = {})
|
||||
requires :parent
|
||||
super({ :parent => @parent }.merge!(attributes))
|
||||
end
|
||||
|
||||
def set(data=nil)
|
||||
requires :parent
|
||||
service.set_metadata(collection_name, @parent.id, meta_hash(data))
|
||||
end
|
||||
|
||||
def update(data=nil)
|
||||
requires :parent
|
||||
service.update_metadata(collection_name, @parent.id, meta_hash(data))
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
def meta_hash(data=nil)
|
||||
if data.nil?
|
||||
data={}
|
||||
self.each do |meta|
|
||||
if meta.is_a?(Fog::Compute::HP::Meta) then
|
||||
data.store(meta.key, meta.value)
|
||||
else
|
||||
data.store(meta["key"], meta["value"])
|
||||
end
|
||||
end
|
||||
end
|
||||
data
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,5 @@
|
|||
require 'fog/compute/models/server'
|
||||
require 'fog/hp/models/compute/metadata'
|
||||
|
||||
module Fog
|
||||
module Compute
|
||||
|
@ -24,6 +25,8 @@ module Fog
|
|||
attribute :tenant_id
|
||||
attribute :user_id
|
||||
attribute :key_name
|
||||
attribute :security_groups
|
||||
attribute :config_drive
|
||||
# these are implemented as methods
|
||||
attribute :image_id
|
||||
attribute :flavor_id
|
||||
|
@ -31,27 +34,44 @@ module Fog
|
|||
attribute :public_ip_address
|
||||
|
||||
attr_reader :password
|
||||
attr_writer :image_id, :flavor_id
|
||||
attr_writer :private_key, :private_key_path
|
||||
attr_writer :public_key, :public_key_path
|
||||
attr_writer :username, :image_id, :flavor_id, :network_name
|
||||
|
||||
def initialize(attributes = {})
|
||||
# assign these attributes first to prevent race condition with persisted?
|
||||
self.security_groups = attributes.delete(:security_groups)
|
||||
# assign these attributes first to prevent race condition with new_record?
|
||||
self.min_count = attributes.delete(:min_count)
|
||||
self.max_count = attributes.delete(:max_count)
|
||||
self.block_device_mapping = attributes.delete(:block_device_mapping)
|
||||
super
|
||||
end
|
||||
|
||||
def console_output(num_lines)
|
||||
requires :id
|
||||
service.get_console_output(id, num_lines)
|
||||
end
|
||||
|
||||
def metadata
|
||||
@metadata ||= begin
|
||||
Fog::Compute::HP::Metadata.new({
|
||||
:service => service,
|
||||
:parent => self
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
def metadata=(new_metadata={})
|
||||
metas = []
|
||||
new_metadata.each_pair {|k,v| metas << {"key" => k, "value" => v} }
|
||||
metadata.load(metas)
|
||||
end
|
||||
|
||||
def destroy
|
||||
requires :id
|
||||
service.delete_server(id)
|
||||
true
|
||||
end
|
||||
|
||||
def images
|
||||
requires :id
|
||||
service.images(:server => self)
|
||||
end
|
||||
|
||||
def key_pair
|
||||
requires :key_name
|
||||
|
||||
|
@ -62,16 +82,29 @@ module Fog
|
|||
self.key_name = new_keypair && new_keypair.name
|
||||
end
|
||||
|
||||
def network_name
|
||||
@network_name ||= "private"
|
||||
end
|
||||
|
||||
def private_ip_address
|
||||
addr = addresses.nil? ? nil : addresses.fetch('private', []).first
|
||||
addr = addresses.nil? ? nil : addresses.fetch(network_name, []).first
|
||||
addr["addr"] if addr
|
||||
end
|
||||
|
||||
def private_key_path
|
||||
@private_key_path ||= Fog.credentials[:private_key_path]
|
||||
@private_key_path &&= File.expand_path(@private_key_path)
|
||||
end
|
||||
|
||||
def private_key
|
||||
@private_key ||= private_key_path && File.read(private_key_path)
|
||||
end
|
||||
|
||||
def public_ip_address
|
||||
# FIX: Both the private and public ips are bundled under "private" network name
|
||||
# So hack to get to the public ip address
|
||||
if !addresses.nil?
|
||||
addr = addresses.fetch('private', [])
|
||||
addr = addresses.fetch(network_name, [])
|
||||
# if we have more than 1 address, then the return the second address which is public
|
||||
if addr.count > 1
|
||||
addr[1]["addr"]
|
||||
|
@ -83,6 +116,15 @@ module Fog
|
|||
end
|
||||
end
|
||||
|
||||
def public_key_path
|
||||
@public_key_path ||= Fog.credentials[:public_key_path]
|
||||
@public_key_path &&= File.expand_path(@public_key_path)
|
||||
end
|
||||
|
||||
def public_key
|
||||
@public_key ||= public_key_path && File.read(public_key_path)
|
||||
end
|
||||
|
||||
def image_id
|
||||
@image_id ||= (image.nil? ? nil : image["id"])
|
||||
end
|
||||
|
@ -107,12 +149,8 @@ module Fog
|
|||
@max_count = new_max_count
|
||||
end
|
||||
|
||||
def security_groups=(new_security_groups)
|
||||
@security_groups = new_security_groups
|
||||
end
|
||||
|
||||
def security_groups
|
||||
@security_groups
|
||||
def block_device_mapping=(new_block_device_mapping)
|
||||
@block_device_mapping = new_block_device_mapping
|
||||
end
|
||||
|
||||
def ready?
|
||||
|
@ -125,6 +163,11 @@ module Fog
|
|||
true
|
||||
end
|
||||
|
||||
def windows_password()
|
||||
requires :id
|
||||
service.get_windows_password(id)
|
||||
end
|
||||
|
||||
def reboot(type = 'SOFT')
|
||||
requires :id
|
||||
service.reboot_server(id, type)
|
||||
|
@ -160,21 +203,38 @@ module Fog
|
|||
service.create_image(id, name, metadata)
|
||||
end
|
||||
|
||||
def volume_attachments
|
||||
requires :id
|
||||
if vols = service.list_server_volumes(id).body
|
||||
vols["volumeAttachments"]
|
||||
end
|
||||
end
|
||||
|
||||
def save
|
||||
raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if persisted?
|
||||
requires :flavor_id, :image_id, :name
|
||||
requires :flavor_id, :name
|
||||
meta_hash = {}
|
||||
metadata.each { |meta| meta_hash.store(meta.key, meta.value) }
|
||||
options = {
|
||||
'metadata' => metadata,
|
||||
'metadata' => meta_hash,
|
||||
'personality' => personality,
|
||||
'accessIPv4' => accessIPv4,
|
||||
'accessIPv6' => accessIPv6,
|
||||
'min_count' => @min_count,
|
||||
'max_count' => @max_count,
|
||||
'key_name' => key_name,
|
||||
'security_groups' => @security_groups
|
||||
'security_groups' => security_groups,
|
||||
'config_drive' => config_drive
|
||||
}
|
||||
options = options.reject {|key, value| value.nil?}
|
||||
data = service.create_server(name, flavor_id, image_id, options)
|
||||
# either create a regular server or a persistent server based on input
|
||||
if image_id
|
||||
# create a regular server using the image
|
||||
data = service.create_server(name, flavor_id, image_id, options)
|
||||
elsif image_id.nil? && !@block_device_mapping.nil? && !@block_device_mapping.empty?
|
||||
# create a persistent server using the bootable volume in the block_device_mapping
|
||||
data = service.create_persistent_server(name, flavor_id, @block_device_mapping, options)
|
||||
end
|
||||
merge_attributes(data.body['server'])
|
||||
true
|
||||
end
|
||||
|
@ -193,6 +253,10 @@ module Fog
|
|||
retry
|
||||
end
|
||||
|
||||
def username
|
||||
@username ||= 'root'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def adminPass=(new_admin_pass)
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class HP
|
||||
module MetaParent
|
||||
|
||||
def parent
|
||||
@parent
|
||||
end
|
||||
|
||||
def parent=(new_parent)
|
||||
@parent = new_parent
|
||||
end
|
||||
|
||||
def collection_name
|
||||
if @parent.class == Fog::Compute::HP::Image
|
||||
return "images"
|
||||
elsif @parent.class == Fog::Compute::HP::Server
|
||||
return "servers"
|
||||
else
|
||||
raise "Metadata is not supported for this model type."
|
||||
end
|
||||
end
|
||||
|
||||
def metas_to_hash(metas)
|
||||
hash = {}
|
||||
metas.each { |meta| hash.store(meta.key, meta.value) }
|
||||
hash
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -14,10 +14,39 @@ module Fog
|
|||
load(data)
|
||||
end
|
||||
|
||||
def head(key, options = {})
|
||||
data = service.head_container(key)
|
||||
directory = create_directory(key, data)
|
||||
# set the cdn state for the directory
|
||||
directory.cdn_enabled?
|
||||
|
||||
directory
|
||||
rescue Fog::Storage::HP::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
def get(key, options = {})
|
||||
data = service.get_container(key, options)
|
||||
directory = create_directory(key, data)
|
||||
# set the files for the directory
|
||||
directory.files.merge_attributes(options)
|
||||
directory.files.instance_variable_set(:@loaded, true)
|
||||
data.body.each do |file|
|
||||
directory.files << directory.files.new(file)
|
||||
end
|
||||
# set the cdn state for the directory
|
||||
directory.cdn_enabled?
|
||||
|
||||
directory
|
||||
rescue Fog::Storage::HP::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_directory(key, data)
|
||||
read_header = nil
|
||||
write_header = nil
|
||||
data = service.get_container(key, options)
|
||||
directory = new(:key => key)
|
||||
for key, value in data.headers
|
||||
if ['X-Container-Bytes-Used', 'X-Container-Object-Count'].include?(key)
|
||||
|
@ -31,16 +60,12 @@ module Fog
|
|||
end
|
||||
# set the acl on the directory based on the headers
|
||||
if !(read_header.nil? && write_header.nil?)
|
||||
directory.acl = service.header_to_acl(read_header, write_header)
|
||||
end
|
||||
directory.files.merge_attributes(options)
|
||||
directory.files.instance_variable_set(:@loaded, true)
|
||||
data.body.each do |file|
|
||||
directory.files << directory.files.new(file)
|
||||
read_acl, write_acl = service.header_to_perm_acl(read_header, write_header)
|
||||
# do not want to expose the read_acl and write_acl as writable attributes
|
||||
directory.instance_variable_set(:@read_acl, read_acl)
|
||||
directory.instance_variable_set(:@write_acl, write_acl)
|
||||
end
|
||||
directory
|
||||
rescue Fog::Storage::HP::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -12,15 +12,86 @@ module Fog
|
|||
attribute :bytes, :aliases => 'X-Container-Bytes-Used'
|
||||
attribute :count, :aliases => 'X-Container-Object-Count'
|
||||
|
||||
def acl=(new_acl)
|
||||
if new_acl.nil?
|
||||
new_acl = "private"
|
||||
def initialize(attributes = {})
|
||||
@read_acl = []
|
||||
@write_acl = []
|
||||
super
|
||||
end
|
||||
|
||||
def read_acl
|
||||
@read_acl || []
|
||||
end
|
||||
|
||||
def write_acl
|
||||
@write_acl || []
|
||||
end
|
||||
|
||||
def can_read?(user)
|
||||
return false if @read_acl.nil?
|
||||
list_users_with_read.include?(user)
|
||||
end
|
||||
|
||||
def can_write?(user)
|
||||
return false if @write_acl.nil?
|
||||
list_users_with_write.include?(user)
|
||||
end
|
||||
|
||||
def can_read_write?(user)
|
||||
can_read?(user) && can_write?(user)
|
||||
end
|
||||
|
||||
def list_users_with_read
|
||||
users = []
|
||||
users = @read_acl.map {|acl| acl.split(':')[1]} unless @read_acl.nil?
|
||||
return users
|
||||
end
|
||||
|
||||
def list_users_with_write
|
||||
users = []
|
||||
users = @write_acl.map {|acl| acl.split(':')[1]} unless @write_acl.nil?
|
||||
return users
|
||||
end
|
||||
|
||||
def grant(perm, users=nil)
|
||||
# support passing in a list of users in a comma-separated list or as an Array
|
||||
if users.is_a?(String)
|
||||
user_list = users.split(',')
|
||||
else
|
||||
user_list = users
|
||||
end
|
||||
valid_acls = ['private', 'public-read', 'public-write', 'public-read-write']
|
||||
unless valid_acls.include?(new_acl)
|
||||
raise ArgumentError.new("acl must be one of [#{valid_acls.join(', ')}]")
|
||||
r_acl, w_acl = service.perm_to_acl(perm, user_list)
|
||||
unless r_acl.nil? || r_acl.empty?
|
||||
@read_acl = [] if @read_acl.nil?
|
||||
@read_acl = @read_acl + r_acl
|
||||
@read_acl.uniq!
|
||||
end
|
||||
@acl = new_acl
|
||||
unless w_acl.nil? || w_acl.empty?
|
||||
@write_acl = [] if @write_acl.nil?
|
||||
@write_acl = @write_acl + w_acl
|
||||
@write_acl.uniq!
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def revoke(perm, users=nil)
|
||||
# support passing in a list of users in a comma-separated list or as an Array
|
||||
if users.is_a?(String)
|
||||
user_list = users.split(',')
|
||||
else
|
||||
user_list = users
|
||||
end
|
||||
r_acl, w_acl = service.perm_to_acl(perm, user_list)
|
||||
unless r_acl.nil? || r_acl.empty?
|
||||
@read_acl = [] if @read_acl.nil?
|
||||
@read_acl = @read_acl - r_acl
|
||||
@read_acl.uniq!
|
||||
end
|
||||
unless w_acl.nil? || w_acl.empty?
|
||||
@write_acl = [] if @write_acl.nil?
|
||||
@write_acl = @write_acl - w_acl
|
||||
@write_acl.uniq!
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
@ -50,18 +121,19 @@ module Fog
|
|||
|
||||
def public=(new_public)
|
||||
if new_public
|
||||
@acl = 'public-read'
|
||||
self.grant("pr")
|
||||
else
|
||||
@acl = 'private'
|
||||
self.revoke("pr")
|
||||
end
|
||||
@public = new_public
|
||||
end
|
||||
|
||||
def public?
|
||||
if @acl.nil?
|
||||
false
|
||||
@read_acl = [] if @read_acl.nil?
|
||||
if @read_acl.include?(".r:*")
|
||||
true
|
||||
else
|
||||
@acl == 'public-read'
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -70,7 +142,7 @@ module Fog
|
|||
@public_url ||= begin
|
||||
begin response = service.head_container(key)
|
||||
# escape the key to cover for special char. in container names
|
||||
url = "#{service.url}/#{Fog::HP.escape(key)}"
|
||||
url = service.public_url(key)
|
||||
rescue Fog::Storage::HP::NotFound => err
|
||||
nil
|
||||
end
|
||||
|
@ -96,7 +168,8 @@ module Fog
|
|||
else
|
||||
@cdn_enable = false
|
||||
end
|
||||
rescue Fog::CDN::HP::NotFound => err
|
||||
# If CDN endpoint is unreachable, a SocketError is raised
|
||||
rescue Fog::CDN::HP::NotFound, Excon::Errors::SocketError
|
||||
@cdn_enable = false
|
||||
end
|
||||
else
|
||||
|
@ -110,24 +183,32 @@ module Fog
|
|||
# return the CDN public url from the appropriate uri from the header
|
||||
begin response = service.cdn.head_container(key)
|
||||
if response.headers['X-Cdn-Enabled'] == 'True'
|
||||
if service.hp_cdn_ssl == true
|
||||
response.headers.fetch('X-Cdn-Ssl-Uri', nil)
|
||||
else
|
||||
response.headers.fetch('X-Cdn-Uri', nil)
|
||||
end
|
||||
response.headers.fetch('X-Cdn-Uri', nil)
|
||||
end
|
||||
rescue Fog::CDN::HP::NotFound => err
|
||||
rescue Fog::CDN::HP::NotFound
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def save
|
||||
def cdn_public_ssl_url
|
||||
requires :key
|
||||
options = {}
|
||||
if @acl
|
||||
options.merge!(service.acl_to_header(@acl))
|
||||
@cdn_public_ssl_url ||= begin
|
||||
# return the CDN public ssl url from the appropriate uri from the header
|
||||
begin response = service.cdn.head_container(key)
|
||||
if response.headers['X-Cdn-Enabled'] == 'True'
|
||||
response.headers.fetch('X-Cdn-Ssl-Uri', nil)
|
||||
end
|
||||
rescue Fog::CDN::HP::NotFound
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def save(options = {})
|
||||
requires :key
|
||||
# write out the acls into the headers before save
|
||||
options.merge!(service.perm_acl_to_header(@read_acl, @write_acl))
|
||||
service.put_container(key, options)
|
||||
# Added an extra check to see if CDN is enabled for the container
|
||||
if (!service.cdn.nil? && service.cdn.enabled?)
|
||||
|
@ -137,16 +218,20 @@ module Fog
|
|||
begin response = service.cdn.head_container(key)
|
||||
### Deleting a container from CDN is much more expensive than flipping the bit to disable it
|
||||
service.cdn.post_container(key, {'X-CDN-Enabled' => 'True'})
|
||||
rescue Fog::CDN::HP::NotFound => err
|
||||
rescue Fog::CDN::HP::NotFound
|
||||
service.cdn.put_container(key)
|
||||
rescue Excon::Errors::SocketError
|
||||
# means that the CDN endpoint is unreachable
|
||||
end
|
||||
else
|
||||
# check to make sure that the container exists. If yes, cdn disable it.
|
||||
begin response = service.cdn.head_container(key)
|
||||
### Deleting a container from CDN is much more expensive than flipping the bit to disable it
|
||||
service.cdn.post_container(key, {'X-CDN-Enabled' => 'False'})
|
||||
rescue Fog::CDN::HP::NotFound => err
|
||||
rescue Fog::CDN::HP::NotFound
|
||||
# just continue, as container is not cdn-enabled.
|
||||
rescue Excon::Errors::SocketError
|
||||
# means that the CDN endpoint is unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -65,6 +65,16 @@ module Fog
|
|||
self.collection.get_cdn_url(self.key)
|
||||
end
|
||||
|
||||
def cdn_public_ssl_url
|
||||
requires :key
|
||||
self.collection.get_cdn_ssl_url(self.key)
|
||||
end
|
||||
|
||||
def temp_signed_url(expires_secs, method)
|
||||
requires :directory, :key
|
||||
service.get_object_temp_url(directory.key, key, expires_secs, method)
|
||||
end
|
||||
|
||||
def save(options = {})
|
||||
requires :body, :directory, :key
|
||||
options['Content-Type'] = content_type if content_type
|
||||
|
|
|
@ -80,6 +80,14 @@ module Fog
|
|||
end
|
||||
end
|
||||
|
||||
def get_cdn_ssl_url(key)
|
||||
requires :directory
|
||||
if self.directory.cdn_public_ssl_url
|
||||
# escape the key to cover for special char. in object names
|
||||
"#{self.directory.cdn_public_ssl_url}/#{Fog::HP.escape(key)}"
|
||||
end
|
||||
end
|
||||
|
||||
def head(key, options = {})
|
||||
requires :directory
|
||||
data = service.head_object(directory.key, key)
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/hp/models/storage/shared_directory'
|
||||
|
||||
module Fog
|
||||
module Storage
|
||||
class HP
|
||||
|
||||
class SharedDirectories < Fog::Collection
|
||||
|
||||
model Fog::Storage::HP::SharedDirectory
|
||||
|
||||
def all
|
||||
nil
|
||||
end
|
||||
|
||||
def head(url)
|
||||
data = service.head_shared_container(url)
|
||||
shared_directory = new(:url => url)
|
||||
for key, value in data.headers
|
||||
if ['X-Container-Bytes-Used', 'X-Container-Object-Count'].include?(key)
|
||||
shared_directory.merge_attributes(key => value)
|
||||
end
|
||||
end
|
||||
|
||||
shared_directory
|
||||
# throws exception Fog::HP::Errors::Forbidden if insufficient access
|
||||
rescue Fog::Storage::HP::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
def get(url)
|
||||
data = service.get_shared_container(url)
|
||||
shared_directory = new(:url => url)
|
||||
for key, value in data.headers
|
||||
if ['X-Container-Bytes-Used', 'X-Container-Object-Count'].include?(key)
|
||||
shared_directory.merge_attributes(key => value)
|
||||
end
|
||||
end
|
||||
# set the files for the directory
|
||||
shared_directory.files.instance_variable_set(:@loaded, true)
|
||||
data.body.each do |file|
|
||||
shared_directory.files << shared_directory.files.new(file)
|
||||
end
|
||||
|
||||
shared_directory
|
||||
# throws exception Fog::HP::Errors::Forbidden if insufficient access
|
||||
rescue Fog::Storage::HP::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,39 @@
|
|||
require 'fog/core/model'
|
||||
require 'fog/hp/models/storage/shared_files'
|
||||
|
||||
module Fog
|
||||
module Storage
|
||||
class HP
|
||||
|
||||
class SharedDirectory < Fog::Model
|
||||
|
||||
identity :url
|
||||
|
||||
attribute :bytes, :aliases => 'X-Container-Bytes-Used'
|
||||
attribute :count, :aliases => 'X-Container-Object-Count'
|
||||
|
||||
def files
|
||||
@files ||= begin
|
||||
Fog::Storage::HP::SharedFiles.new(
|
||||
:shared_directory => self,
|
||||
:service => service
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
requires :url
|
||||
# delete is not allowed
|
||||
false
|
||||
end
|
||||
|
||||
def save(options = {})
|
||||
requires :url
|
||||
# put is not allowed
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,67 @@
|
|||
require 'fog/core/model'
|
||||
|
||||
module Fog
|
||||
module Storage
|
||||
class HP
|
||||
|
||||
class SharedFile < Fog::Model
|
||||
|
||||
identity :key, :aliases => 'name'
|
||||
attribute :url
|
||||
|
||||
attribute :content_length, :aliases => ['bytes', 'Content-Length'], :type => :integer
|
||||
attribute :content_type, :aliases => ['content_type', 'Content-Type']
|
||||
attribute :etag, :aliases => ['hash', 'Etag']
|
||||
attribute :last_modified, :aliases => ['last_modified', 'Last-Modified'], :type => :time
|
||||
|
||||
def url
|
||||
"#{self.collection.shared_directory.url}/#{key}"
|
||||
end
|
||||
|
||||
def body
|
||||
attributes[:body] ||= if last_modified
|
||||
collection.get(identity).body
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
def body=(new_body)
|
||||
attributes[:body] = new_body
|
||||
end
|
||||
|
||||
def destroy
|
||||
requires :shared_directory, :key
|
||||
service.delete_shared_object(self.url)
|
||||
true
|
||||
# throws exception Fog::HP::Errors::Forbidden if insufficient access
|
||||
rescue Fog::Storage::HP::NotFound
|
||||
false
|
||||
end
|
||||
|
||||
def shared_directory
|
||||
@shared_directory
|
||||
end
|
||||
|
||||
def save(options = {})
|
||||
requires :shared_directory, :key
|
||||
options['Content-Type'] = content_type if content_type
|
||||
data = service.put_shared_object(shared_directory.url, key, body, options)
|
||||
merge_attributes(data.headers)
|
||||
self.content_length = Fog::Storage.get_body_size(body)
|
||||
true
|
||||
# throws exception Fog::HP::Errors::Forbidden if insufficient access
|
||||
rescue Fog::Storage::HP::NotFound
|
||||
false
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def shared_directory=(new_shared_directory)
|
||||
@shared_directory = new_shared_directory
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,64 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/hp/models/storage/shared_file'
|
||||
|
||||
module Fog
|
||||
module Storage
|
||||
class HP
|
||||
|
||||
class SharedFiles < Fog::Collection
|
||||
|
||||
attribute :shared_directory
|
||||
|
||||
model Fog::Storage::HP::SharedFile
|
||||
|
||||
def all
|
||||
requires :shared_directory
|
||||
parent = shared_directory.collection.get(shared_directory.url)
|
||||
if parent
|
||||
load(parent.files.map {|file| file.attributes})
|
||||
else
|
||||
nil
|
||||
end
|
||||
# throws exception Fog::HP::Errors::Forbidden if insufficient access
|
||||
rescue Fog::Storage::HP::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
def get(key, &block)
|
||||
requires :shared_directory
|
||||
shared_object_url = "#{shared_directory.url}/#{key}"
|
||||
data = service.get_shared_object(shared_object_url, &block)
|
||||
file_data = data.headers.merge({
|
||||
:body => data.body,
|
||||
:key => key
|
||||
})
|
||||
new(file_data)
|
||||
# throws exception Fog::HP::Errors::Forbidden if insufficient access
|
||||
rescue Fog::Storage::HP::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
def head(key)
|
||||
requires :shared_directory
|
||||
shared_object_url = "#{shared_directory.url}/#{key}"
|
||||
data = service.head_shared_object(shared_object_url)
|
||||
file_data = data.headers.merge({
|
||||
:body => '',
|
||||
:key => key
|
||||
})
|
||||
new(file_data)
|
||||
# throws exception Fog::HP::Errors::Forbidden if insufficient access
|
||||
rescue Fog::Storage::HP::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
def new(attributes = {})
|
||||
requires :shared_directory
|
||||
super({ :shared_directory => shared_directory }.merge!(attributes))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,76 @@
|
|||
module Fog
|
||||
module HP
|
||||
class BlockStorage
|
||||
class Real
|
||||
|
||||
# Create a new block storage snapshot
|
||||
#
|
||||
# ==== Parameters
|
||||
# * name<~String> - Name of the snapshot
|
||||
# * description<~String> - Description of the snapshot
|
||||
# * volume_id<~Integer> - Id of the volume to create snapshot of
|
||||
# * options<~Hash>:
|
||||
# * 'force'<~Boolean> - Not implemented yet. True or False, to allow online snapshots (i.e. when volume is attached)
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Hash>:
|
||||
# * snapshot<~Hash>:
|
||||
# * 'id'<~Integer>: - Id for the snapshot
|
||||
# * 'displayName'<~String>: - Name of the snapshot
|
||||
# * 'displayDescription'<~String>: - Description of the snapshot
|
||||
# * 'size'<~Integer>: - Size in GB for the snapshot
|
||||
# * 'status'<~String>: - Status of the snapshot i.e. "creating"
|
||||
# * 'volumeId'<~Integer>: - Id of the volume from which the snapshot was created
|
||||
# * 'createdAt'<~String>: - Timestamp in UTC when snapshot was created
|
||||
def create_snapshot(name, description, volume_id, options={})
|
||||
data = {
|
||||
'snapshot' => {
|
||||
'display_name' => name,
|
||||
'display_description' => description,
|
||||
'volume_id' => volume_id
|
||||
}
|
||||
}
|
||||
|
||||
l_options = ['force']
|
||||
l_options.select{|o| options[o]}.each do |key|
|
||||
data['snapshot'][key] = options[key]
|
||||
end
|
||||
|
||||
request(
|
||||
:body => Fog::JSON.encode(data),
|
||||
:expects => 200,
|
||||
:method => 'POST',
|
||||
:path => "os-snapshots"
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def create_snapshot(name, description, volume_id, options={})
|
||||
response = Excon::Response.new
|
||||
if self.data[:volumes][volume_id]
|
||||
response.status = 200
|
||||
data = {
|
||||
'id' => Fog::Mock.random_numbers(3).to_i,
|
||||
'displayName' => name,
|
||||
'displayDescription' => description,
|
||||
'size' => self.data[:volumes][volume_id]['size'],
|
||||
'status' => 'available',
|
||||
'volumeId' => volume_id,
|
||||
'createdAt' => Time.now.to_s
|
||||
}
|
||||
self.data[:snapshots][data['id']] = data
|
||||
response.body = { 'snapshot' => data }
|
||||
else
|
||||
raise Fog::HP::BlockStorage::NotFound
|
||||
end
|
||||
response
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,87 @@
|
|||
module Fog
|
||||
module HP
|
||||
class BlockStorage
|
||||
class Real
|
||||
|
||||
# Create a new block storage volume
|
||||
#
|
||||
# ==== Parameters
|
||||
# * name<~String> - Name of the volume
|
||||
# * description<~String> - Description of the volume
|
||||
# * size<~Integer> - Size of the volume (in GBs)
|
||||
# * options<~Hash>:
|
||||
# * 'snapshot_id'<~String> - Id of the volume snapshot to create the volume from. The request is invalid if both the snapshot_id and the imageRef parameters are specified and are not null.
|
||||
# * 'imageRef'<~String> - Id of the image to create the volume from. This creates a bootable volume. The request is invalid if both the snapshot_id and the imageRef parameters are specified and are not null.
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Hash>:
|
||||
# * volume<~Hash>:
|
||||
# * 'id'<~Integer> - Id for the volume
|
||||
# * 'displayName'<~String> - Name of the volume
|
||||
# * 'displayDescription'<~String> - Description of the volume
|
||||
# * 'size'<~Integer> - Size in GB for the volume
|
||||
# * 'status'<~String> - Status of the volume i.e. "creating"
|
||||
# * 'volumeType'<~String> - Type of the volume
|
||||
# * 'snapshotId'<~String> - Id of the snapshot, the volume was created from.
|
||||
# * 'imageRef'<~String> - Id of the image, the volume was created from. A not null value means it is a bootable volume.
|
||||
# * 'createdAt'<~String> - Timestamp in UTC when volume was created
|
||||
# * 'availabilityZone'<~String> - Availability zone i.e. "nova"
|
||||
# * attachments<~Array>: Array of hashes of attachments
|
||||
# * metadata<~Hash>: Hash of metadata for the volume
|
||||
def create_volume(name, description, size, options={})
|
||||
data = {
|
||||
'volume' => {
|
||||
'display_name' => name,
|
||||
'display_description' => description,
|
||||
'size' => size
|
||||
}
|
||||
}
|
||||
|
||||
l_options = ['snapshot_id', 'imageRef', 'metadata']
|
||||
l_options.select{|o| options[o]}.each do |key|
|
||||
data['volume'][key] = options[key]
|
||||
end
|
||||
|
||||
request(
|
||||
:body => Fog::JSON.encode(data),
|
||||
:expects => 200,
|
||||
:method => 'POST',
|
||||
:path => "os-volumes"
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def create_volume(name, description, size, options={})
|
||||
if options['snapshotId'] && options['imageRef']
|
||||
raise Fog::Errors::BadRequest.new("Snapshot and image cannot be specified together.")
|
||||
else
|
||||
response = Excon::Response.new
|
||||
response.status = 200
|
||||
data = {
|
||||
'id' => Fog::Mock.random_numbers(3).to_i,
|
||||
'displayName' => name,
|
||||
'displayDescription' => description,
|
||||
'size' => size,
|
||||
'status' => 'available',
|
||||
'snapshotId' => options['snapshot_id'] || "",
|
||||
#'imageRef' => options['imageRef'] || "", # TODO: not implemented to preserve backward compatibility
|
||||
'volumeType' => nil,
|
||||
'availabilityZone' => 'nova',
|
||||
'createdAt' => Time.now.to_s,
|
||||
'metadata' => options['metadata'] || {},
|
||||
'attachments' => [{}]
|
||||
}
|
||||
self.data[:volumes][data['id']] = data
|
||||
response.body = { 'volume' => data }
|
||||
response
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,38 @@
|
|||
module Fog
|
||||
module HP
|
||||
class BlockStorage
|
||||
class Real
|
||||
|
||||
# Delete an existing block storage snapshot
|
||||
#
|
||||
# ==== Parameters
|
||||
# * snapshot_id<~Integer> - Id of the snapshot to delete
|
||||
#
|
||||
def delete_snapshot(snapshot_id)
|
||||
response = request(
|
||||
:expects => 202,
|
||||
:method => 'DELETE',
|
||||
:path => "os-snapshots/#{snapshot_id}"
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def delete_snapshot(snapshot_id)
|
||||
response = Excon::Response.new
|
||||
if self.data[:snapshots][snapshot_id]
|
||||
self.data[:snapshots].delete(snapshot_id)
|
||||
response.status = 202
|
||||
else
|
||||
raise Fog::HP::BlockStorage::NotFound
|
||||
end
|
||||
response
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,38 @@
|
|||
module Fog
|
||||
module HP
|
||||
class BlockStorage
|
||||
class Real
|
||||
|
||||
# Delete an existing block storage volume
|
||||
#
|
||||
# ==== Parameters
|
||||
# * volume_id<~Integer> - Id of the volume to delete
|
||||
#
|
||||
def delete_volume(volume_id)
|
||||
response = request(
|
||||
:expects => 202,
|
||||
:method => 'DELETE',
|
||||
:path => "os-volumes/#{volume_id}"
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def delete_volume(volume_id)
|
||||
response = Excon::Response.new
|
||||
if self.data[:volumes][volume_id]
|
||||
self.data[:volumes].delete(volume_id)
|
||||
response.status = 202
|
||||
else
|
||||
raise Fog::HP::BlockStorage::NotFound
|
||||
end
|
||||
response
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,59 @@
|
|||
module Fog
|
||||
module HP
|
||||
class BlockStorage
|
||||
class Real
|
||||
|
||||
# Get details for existing block storage bootable volume
|
||||
#
|
||||
# ==== Parameters
|
||||
# * volume_id<~Integer> - Id of the volume to get
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Hash>:
|
||||
# * volume<~Hash>:
|
||||
# * 'id'<~Integer> - Id for the volume
|
||||
# * 'displayName'<~String> - Name of the volume
|
||||
# * 'displayDescription'<~String> - Description of the volume
|
||||
# * 'size'<~Integer> - Size in GB for the volume
|
||||
# * 'status'<~String> - Status of the volume i.e. "available"
|
||||
# * 'volumeType'<~String> - Type of the volume
|
||||
# * 'snapshotId'<~String> - Id of the volume snapshot
|
||||
# * 'sourceImageRef'<~String> - Id of the volume snapshot
|
||||
# * 'createdAt'<~String> - Timestamp in UTC when volume was created
|
||||
# * 'availabilityZone'<~String> - Availability zone i.e. "nova"
|
||||
# * attachments<~Array> Array of hashes of attachments
|
||||
# * metadata<~Hash> Hash of metadata for the volume
|
||||
|
||||
def get_bootable_volume_details(volume_id)
|
||||
response = request(
|
||||
:expects => 200,
|
||||
:method => 'GET',
|
||||
:path => "hp-bootable-volumes/#{volume_id}"
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def get_bootable_volume_details(volume_id)
|
||||
unless volume_id
|
||||
raise ArgumentError.new('volume_id is required')
|
||||
end
|
||||
response = Excon::Response.new
|
||||
if volume = self.data[:volumes][volume_id]
|
||||
response.status = 200
|
||||
response.body = { 'volume' => volume }
|
||||
response
|
||||
else
|
||||
raise Fog::HP::BlockStorage::NotFound
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,54 @@
|
|||
module Fog
|
||||
module HP
|
||||
class BlockStorage
|
||||
class Real
|
||||
|
||||
# Get details for existing block storage snapshot
|
||||
#
|
||||
# ==== Parameters
|
||||
# * snapshot_id<~Integer> - Id of the snapshot to get
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Hash>:
|
||||
# * snapshot<~Hash>:
|
||||
# * 'id'<~Integer>: - Id for the snapshot
|
||||
# * 'displayName'<~String>: - Name of the snapshot
|
||||
# * 'displayDescription'<~String>: - Description of the snapshot
|
||||
# * 'size'<~Integer>: - Size in GB for the snapshot
|
||||
# * 'status'<~String>: - Status of the snapshot i.e. "available"
|
||||
# * 'volumeId'<~Integer>: - Id of the volume from which the snapshot was created
|
||||
# * 'createdAt'<~String>: - Timestamp in UTC when volume was created
|
||||
|
||||
def get_snapshot_details(snapshot_id)
|
||||
response = request(
|
||||
:expects => 200,
|
||||
:method => 'GET',
|
||||
:path => "os-snapshots/#{snapshot_id}"
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def get_snapshot_details(snapshot_id)
|
||||
unless snapshot_id
|
||||
raise ArgumentError.new('snapshot_id is required')
|
||||
end
|
||||
response = Excon::Response.new
|
||||
if snapshot = self.data[:snapshots][snapshot_id]
|
||||
response.status = 200
|
||||
response.body = { 'snapshot' => snapshot }
|
||||
response
|
||||
else
|
||||
raise Fog::HP::BlockStorage::NotFound
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,58 @@
|
|||
module Fog
|
||||
module HP
|
||||
class BlockStorage
|
||||
class Real
|
||||
|
||||
# Get details for existing block storage volume
|
||||
#
|
||||
# ==== Parameters
|
||||
# * volume_id<~Integer> - Id of the volume to get
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Hash>:
|
||||
# * volume<~Hash>:
|
||||
# * 'id'<~Integer>: - Id for the volume
|
||||
# * 'displayName'<~String>: - Name of the volume
|
||||
# * 'displayDescription'<~String>: - Description of the volume
|
||||
# * 'size'<~Integer>: - Size in GB for the volume
|
||||
# * 'status'<~String>: - Status of the volume i.e. "available"
|
||||
# * 'volumeType'<~String>: - Type of the volume
|
||||
# * 'snapshotId'<~String>: - Id of the volume snapshot
|
||||
# * 'createdAt'<~String>: - Timestamp in UTC when volume was created
|
||||
# * 'availabilityZone'<~String>: - Availability zone i.e. "nova"
|
||||
# * attachments<~Array>: Array of hashes of attachments
|
||||
# * metadata<~Hash>: Hash of metadata for the volume
|
||||
|
||||
def get_volume_details(volume_id)
|
||||
response = request(
|
||||
:expects => 200,
|
||||
:method => 'GET',
|
||||
:path => "os-volumes/#{volume_id}"
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def get_volume_details(volume_id)
|
||||
unless volume_id
|
||||
raise ArgumentError.new('volume_id is required')
|
||||
end
|
||||
response = Excon::Response.new
|
||||
if volume = self.data[:volumes][volume_id]
|
||||
response.status = 200
|
||||
response.body = { 'volume' => volume }
|
||||
response
|
||||
else
|
||||
raise Fog::HP::BlockStorage::NotFound
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,53 @@
|
|||
module Fog
|
||||
module HP
|
||||
class BlockStorage
|
||||
class Real
|
||||
|
||||
# List existing block storage bootbale volumes
|
||||
#
|
||||
# ==== Parameters
|
||||
# None
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Array>:
|
||||
# * volumes<~Hash>:
|
||||
# * 'id'<~Integer>: - Id for the volume
|
||||
# * 'displayName'<~String>: - Name of the volume
|
||||
# * 'displayDescription'<~String>: - Description of the volume
|
||||
# * 'size'<~Integer>: - Size in GB for the volume
|
||||
# * 'status'<~String>: - Status of the volume i.e. "available"
|
||||
# * 'volumeType'<~String>: - Type of the volume
|
||||
# * 'snapshotId'<~String>: - Id of the source snapshot used to create volume
|
||||
# * 'sourceImageRef'<~String>: - Id of the source image used to create volume
|
||||
# * 'createdAt'<~String>: - Timestamp in UTC when volume was created
|
||||
# * 'availabilityZone'<~String>: - Availability zone i.e. "nova"
|
||||
# * attachments<~Array>: Array of hashes of attachments
|
||||
# * metadata<~Hash>: Hash of metadata for the volume
|
||||
def list_bootable_volumes
|
||||
response = request(
|
||||
:expects => 200,
|
||||
:method => 'GET',
|
||||
:path => "hp-bootable-volumes"
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def list_bootable_volumes
|
||||
response = Excon::Response.new
|
||||
volumes = []
|
||||
volumes = self.data[:volumes].values unless self.data[:volumes].nil?
|
||||
|
||||
response.status = 200
|
||||
response.body = { 'volumes' => volumes }
|
||||
response
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,48 @@
|
|||
module Fog
|
||||
module HP
|
||||
class BlockStorage
|
||||
class Real
|
||||
|
||||
# List existing block storage snapshots
|
||||
#
|
||||
# ==== Parameters
|
||||
# None
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Array>:
|
||||
# * snapshots<~Hash>:
|
||||
# * 'id'<~Integer>: - Id for the snapshot
|
||||
# * 'displayName'<~String>: - Name of the snapshot
|
||||
# * 'displayDescription'<~String>: - Description of the snapshot
|
||||
# * 'size'<~Integer>: - Size in GB for the snapshot
|
||||
# * 'status'<~String>: - Status of the snapshot i.e. "available"
|
||||
# * 'volumeId'<~Integer>: - Id of the volume from which the snapshot was created
|
||||
# * 'createdAt'<~String>: - Timestamp in UTC when volume was created
|
||||
def list_snapshots
|
||||
response = request(
|
||||
:expects => 200,
|
||||
:method => 'GET',
|
||||
:path => 'os-snapshots'
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def list_snapshots
|
||||
response = Excon::Response.new
|
||||
snapshots = []
|
||||
snapshots = self.data[:snapshots].values unless self.data[:snapshots].nil?
|
||||
|
||||
response.status = 200
|
||||
response.body = { 'snapshots' => snapshots }
|
||||
response
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,52 @@
|
|||
module Fog
|
||||
module HP
|
||||
class BlockStorage
|
||||
class Real
|
||||
|
||||
# List existing block storage volumes
|
||||
#
|
||||
# ==== Parameters
|
||||
# None
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Array>:
|
||||
# * volumes<~Hash>:
|
||||
# * 'id'<~Integer>: - Id for the volume
|
||||
# * 'displayName'<~String>: - Name of the volume
|
||||
# * 'displayDescription'<~String>: - Description of the volume
|
||||
# * 'size'<~Integer>: - Size in GB for the volume
|
||||
# * 'status'<~String>: - Status of the volume i.e. "available"
|
||||
# * 'volumeType'<~String>: - Type of the volume
|
||||
# * 'snapshotId'<~String>: - Id of the volume snapshot
|
||||
# * 'createdAt'<~String>: - Timestamp in UTC when volume was created
|
||||
# * 'availabilityZone'<~String>: - Availability zone i.e. "nova"
|
||||
# * attachments<~Array>: Array of hashes of attachments
|
||||
# * metadata<~Hash>: Hash of metadata for the volume
|
||||
def list_volumes
|
||||
response = request(
|
||||
:expects => 200,
|
||||
:method => 'GET',
|
||||
:path => 'os-volumes'
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def list_volumes
|
||||
response = Excon::Response.new
|
||||
volumes = []
|
||||
volumes = self.data[:volumes].values unless self.data[:volumes].nil?
|
||||
|
||||
response.status = 200
|
||||
response.body = { 'volumes' => volumes }
|
||||
response
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,78 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# Attach a block storage volume to an existing server
|
||||
#
|
||||
# ==== Parameters
|
||||
# * server_id<~Integer> - Id of server to attach the volume to
|
||||
# * volume_id<~Integer> - Id of the volume to be attached to the server
|
||||
# * device<~String> - Device name that is the mount point that the volume will be attached to. e.g. /dev/sdf
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Hash>:
|
||||
# * 'volumeAttachment'<~Hash>:
|
||||
# * <~Hash>
|
||||
# * 'volumeId':<~Integer> - The volume id
|
||||
# * 'device':<~String> - The name of the device
|
||||
def attach_volume(server_id, volume_id, device)
|
||||
data = { 'volumeAttachment' =>
|
||||
{ 'volumeId' => volume_id,
|
||||
'device' => device
|
||||
}
|
||||
}
|
||||
response = request(
|
||||
:body => Fog::JSON.encode(data),
|
||||
:expects => 200,
|
||||
:method => 'POST',
|
||||
:path => "servers/#{server_id}/os-volume_attachments"
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def attach_volume(server_id, volume_id, device)
|
||||
response = Excon::Response.new
|
||||
if server = self.data[:servers][server_id]
|
||||
# mock the case when the volume is already attached to the server
|
||||
if server['volumeAttachments'] && server['volumeAttachments'].select {|v| v['id'] == volume_id}
|
||||
response.status = 400
|
||||
response.body = '{"badRequest": {"message": "Volume status must be available", "code": 400}}'
|
||||
raise(Excon::Errors.status_error({:expects => 200}, response))
|
||||
else
|
||||
resp_data = { "volumeAttachment" =>
|
||||
{
|
||||
"volumeId" => volume_id,
|
||||
"id" => volume_id
|
||||
}
|
||||
}
|
||||
response.body = resp_data
|
||||
response.status = 200
|
||||
|
||||
data = {
|
||||
"device" => device,
|
||||
"serverId" => server_id,
|
||||
"id" => volume_id,
|
||||
"volumeId" => volume_id,
|
||||
}
|
||||
if server['volumeAttachments']
|
||||
server['volumeAttachments'] << data
|
||||
else
|
||||
server['volumeAttachments'] = [data]
|
||||
end
|
||||
end
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -18,10 +18,7 @@ module Fog
|
|||
def create_image(server_id, name, metadata = {})
|
||||
body = { 'createImage' =>
|
||||
{ 'name' => name,
|
||||
'metadata' =>
|
||||
{ 'ImageType' => metadata[:image_type],
|
||||
'ImageVersion' => metadata[:image_version]
|
||||
}
|
||||
'metadata' => metadata
|
||||
}
|
||||
}
|
||||
server_action(server_id, body)
|
||||
|
@ -39,19 +36,19 @@ module Fog
|
|||
|
||||
data = {
|
||||
'id' => image_id,
|
||||
'server' => {"id"=>"3", "links"=>[{"href"=>"http://nova1:8774/v1.1/servers/#{server_id}", "rel"=>"bookmark"}]},
|
||||
'server' => {"id"=>server_id, "links"=>[{"href"=>"http://nova1:8774/v1.1/servers/#{server_id}", "rel"=>"bookmark"}]},
|
||||
'links' => [{"href"=>"http://nova1:8774/v1.1/tenantid/images/#{image_id}", "rel"=>"self"}, {"href"=>"http://nova1:8774/tenantid/images/#{image_id}", "rel"=>"bookmark"}],
|
||||
'metadata' => metadata || {},
|
||||
'name' => name || "image_#{rand(999)}",
|
||||
'progress' => 0,
|
||||
'status' => 'SAVING',
|
||||
'updated' => "",
|
||||
'created' => ""
|
||||
'updated' => "2012-01-01T13:32:20Z",
|
||||
'created' => "2012-01-01T13:32:20Z"
|
||||
}
|
||||
|
||||
self.data[:last_modified][:images][data['id']] = Time.now
|
||||
self.data[:images][data['id']] = data
|
||||
response.headers = {'Content-Length' => '0', 'Content-Type' => 'text/html; charset=UTF-8', 'Date' => Time.now, 'Location' => "http://nova1:8774/v1.1/images/#{@image_id}"}
|
||||
response.headers = {'Content-Length' => '0', 'Content-Type' => 'text/html; charset=UTF-8', 'Date' => Time.now, 'Location' => "http://nova1:8774/v1.1/images/#{image_id}"}
|
||||
response.body = "" # { 'image' => data } no data is sent
|
||||
response
|
||||
end
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# Create a new persistent server i.e. use a bootable volume instead of an image
|
||||
#
|
||||
# ==== Parameters
|
||||
# * name<~String> - Name of server
|
||||
# * flavor_id<~Integer> - Id of flavor for server
|
||||
# * block_device_mapping<~Array>: Use bootable volumes to create persistent instances
|
||||
# * <~Hash>:
|
||||
# * 'volume_size'<~String> - Size of the volume. Ignored, and automatically picked up from the volume
|
||||
# * 'volume_id'<~String> - Id of the bootable volume to use
|
||||
# * 'delete_on_termination'<~String> - Setting this to '1' (True) means that the volume gets deleted when the instance is killed. Set it to '0' to preserve the volume.
|
||||
# * 'device_name'<~String> - Block device name e.g. "vda"
|
||||
# * options<~Hash>:
|
||||
# * 'metadata'<~Hash> - Up to 5 key value pairs containing 255 bytes of info
|
||||
# * 'min_count'<~Integer> - Number of servers to create. Defaults to 1.
|
||||
# * 'max_count'<~Integer> - Max. number of servers to create. Defaults to being equal to min_count.
|
||||
# * 'key_name'<~String> - Name of keypair to be used
|
||||
# * 'security_groups'<~Array> - one or more security groups to be used
|
||||
# * 'personality'<~Array>: Up to 5 files to customize server
|
||||
# * 'file'<~Hash>:
|
||||
# * 'contents'<~String> - Contents of file (10kb total of contents)
|
||||
# * 'path'<~String> - Path to file (255 bytes total of path strings)
|
||||
# * 'accessIPv4'<~String> - IPv4 IP address
|
||||
# * 'accessIPv6'<~String> - IPv6 IP address
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Hash>:
|
||||
# * 'server'<~Hash>:
|
||||
# * 'addresses'<~Hash>:
|
||||
# * 'private'<~Array> - private and public fixed and floating ip addresses
|
||||
# * 'flavor'<~Hash>
|
||||
# * 'id'<~String> - id of the flavor
|
||||
# * 'links'<~Array> - array of flavor links
|
||||
# * 'id'<~Integer> - id of server
|
||||
# * 'links'<~Array> - array of server links
|
||||
# * 'hostId'<~String>
|
||||
# * 'metadata'<~Hash> - metadata
|
||||
# * 'name'<~String> - name of server
|
||||
# * 'accessIPv4'<~String> - IPv4 ip address
|
||||
# * 'accessIPv6'<~String> - IPv6 ip address
|
||||
# * 'progress'<~Integer> - progress through current status
|
||||
# * 'status'<~String> - current server status
|
||||
# * 'created'<~String> - created date time stamp
|
||||
# * 'updated'<~String> - updated date time stamp
|
||||
# * 'user_id'<~String> - user id
|
||||
# * 'tenant_id'<~String> - tenant id
|
||||
# * 'uuid'<~String> - uuid of the server
|
||||
# * 'config_drive'<~String> - config drive
|
||||
# * 'security_groups'<~Array of Hash>
|
||||
# * 'id'<~Integer> - id of the security group
|
||||
# * 'name'<~String> - name of the security group
|
||||
# * 'links'<~Array> - array of security group links
|
||||
# * 'key_name'<~String> - name of the keypair
|
||||
# * 'adminPass'<~String> - admin password for server
|
||||
def create_persistent_server(name, flavor_id, block_device_mapping = [], options = {})
|
||||
data = {
|
||||
'server' => {
|
||||
'flavorRef' => flavor_id,
|
||||
'imageRef' => nil,
|
||||
'name' => name
|
||||
}
|
||||
}
|
||||
if options['metadata']
|
||||
data['server']['metadata'] = options['metadata']
|
||||
end
|
||||
if options['accessIPv4']
|
||||
data['server']['accessIPv4'] = options['accessIPv4']
|
||||
end
|
||||
if options['accessIPv6']
|
||||
data['server']['accessIPv6'] = options['accessIPv6']
|
||||
end
|
||||
if options['personality']
|
||||
data['server']['personality'] = []
|
||||
for file in options['personality']
|
||||
data['server']['personality'] << {
|
||||
'contents' => Base64.encode64(file['contents']),
|
||||
'path' => file['path']
|
||||
}
|
||||
end
|
||||
end
|
||||
min_count = options['min_count'] || 1
|
||||
max_count = options['max_count'] || min_count
|
||||
data['server']['min_count'] = min_count
|
||||
data['server']['max_count'] = max_count
|
||||
|
||||
if options['key_name']
|
||||
data['server']['key_name'] = options['key_name']
|
||||
end
|
||||
if options['security_groups']
|
||||
data['server']['security_groups'] = []
|
||||
for sg in options['security_groups']
|
||||
data['server']['security_groups'] << {
|
||||
'name' => sg
|
||||
}
|
||||
end
|
||||
end
|
||||
if options['config_drive']
|
||||
data['server']['config_drive'] = options['config_drive']
|
||||
end
|
||||
if block_device_mapping
|
||||
data['server']['block_device_mapping'] = block_device_mapping
|
||||
end
|
||||
|
||||
request(
|
||||
:body => Fog::JSON.encode(data),
|
||||
:expects => 200,
|
||||
:method => 'POST',
|
||||
:path => 'os-volumes_boot'
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock
|
||||
|
||||
def create_persistent_server(name, flavor_id, block_device_mapping = [], options = {})
|
||||
response = Excon::Response.new
|
||||
|
||||
if block_device_mapping && !block_device_mapping.empty?
|
||||
|
||||
if options['security_groups']
|
||||
sec_group_name = options['security_groups'][0]
|
||||
else
|
||||
sec_group_name = "default"
|
||||
end
|
||||
|
||||
data = {
|
||||
'addresses' => { "private"=>[{"version"=>4, "addr"=>Fog::HP::Mock.ip_address}] },
|
||||
'flavor' => {"id"=>"#{flavor_id}", "links"=>[{"href"=>"http://nova1:8774/admin/flavors/#{flavor_id}", "rel"=>"bookmark"}]},
|
||||
'id' => Fog::Mock.random_numbers(6).to_i,
|
||||
'links' => [{"href"=>"http://nova1:8774/v1.1/admin/servers/5", "rel"=>"self"}, {"href"=>"http://nova1:8774/admin/servers/5", "rel"=>"bookmark"}],
|
||||
'hostId' => "123456789ABCDEF01234567890ABCDEF",
|
||||
'metadata' => options['metadata'] || {},
|
||||
'name' => name || "server_#{rand(999)}",
|
||||
'accessIPv4' => options['accessIPv4'] || "",
|
||||
'accessIPv6' => options['accessIPv6'] || "",
|
||||
'progress' => 0,
|
||||
'status' => 'BUILD',
|
||||
'created' => "2012-01-01T13:32:20Z",
|
||||
'updated' => "2012-01-01T13:32:20Z",
|
||||
'user_id' => Fog::HP::Mock.user_id.to_s,
|
||||
'tenant_id' => Fog::HP::Mock.user_id.to_s,
|
||||
'uuid' => "95253a45-9ead-43c6-90b3-65da2ef048b3",
|
||||
'config_drive' => "",
|
||||
'security_groups' => [{"name"=>"#{sec_group_name}", "links"=>[{"href"=>"http://nova1:8774/v1.1/admin//os-security-groups/111", "rel"=>"bookmark"}], "id"=>111}],
|
||||
'key_name' => options['key_name'] || ""
|
||||
}
|
||||
self.data[:last_modified][:servers][data['id']] = Time.now
|
||||
self.data[:servers][data['id']] = data
|
||||
response.body = { 'server' => data.merge({'adminPass' => 'password'}) }
|
||||
response.status = 200
|
||||
response
|
||||
else
|
||||
response.status = 400
|
||||
raise(Excon::Errors::BadRequest, "No boot volume or boot image specified")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -8,16 +8,15 @@ module Fog
|
|||
# ==== Parameters
|
||||
# * name<~String> - Name of server
|
||||
# * flavor_id<~Integer> - Id of flavor for server
|
||||
# * image_id<~Integer> - Id of image for server
|
||||
# * image_id<~Integer> - Id of image for server. If block_device_mapping is passed, this is ignored.
|
||||
# * options<~Hash>:
|
||||
# * 'metadata'<~Hash> - Up to 5 key value pairs containing 255 bytes of info
|
||||
# * 'min_count'<~Integer> - Number of servers to create. Defaults to 1.
|
||||
# * 'max_count'<~Integer> - Max. number of servers to create. Defaults to being equal to min_count.
|
||||
# * 'key_name'<~String> - Name of keypair to be used
|
||||
# * 'security_groups'<~Array> - one or more security groups to be used
|
||||
# * 'availability_zone'<~String> - the availability zone to be used
|
||||
# * 'personality'<~Array>: Up to 5 files to customize server
|
||||
# * file<~Hash>:
|
||||
# * 'file'<~Hash>:
|
||||
# * 'contents'<~String> - Contents of file (10kb total of contents)
|
||||
# * 'path'<~String> - Path to file (255 bytes total of path strings)
|
||||
# * 'accessIPv4'<~String> - IPv4 IP address
|
||||
|
@ -28,17 +27,34 @@ module Fog
|
|||
# * body<~Hash>:
|
||||
# * 'server'<~Hash>:
|
||||
# * 'addresses'<~Hash>:
|
||||
# * 'public'<~Array> - public address strings
|
||||
# * 'private'<~Array> - private address strings
|
||||
# * 'adminPass'<~String> - Admin password for server
|
||||
# * 'flavorId'<~Integer> - Id of servers current flavor
|
||||
# * 'private'<~Array> - private and public fixed and floating ip addresses
|
||||
# * 'flavor'<~Hash>
|
||||
# * 'id'<~String> - id of the flavor
|
||||
# * 'links'<~Array> - array of flavor links
|
||||
# * 'id'<~Integer> - id of server
|
||||
# * 'image'<~Hash> - id of image used to boot server
|
||||
# * 'id'<~String> - id of the image
|
||||
# * 'links'<~Array> - array of image links
|
||||
# * 'links'<~Array> - array of server links
|
||||
# * 'hostId'<~String>
|
||||
# * 'id'<~Integer> - Id of server
|
||||
# * 'imageId'<~Integer> - Id of image used to boot server
|
||||
# * 'metadata'<~Hash> - metadata
|
||||
# * 'name'<~String> - Name of server
|
||||
# * 'progress'<~Integer> - Progress through current status
|
||||
# * 'status'<~String> - Current server status
|
||||
# * 'name'<~String> - name of server
|
||||
# * 'accessIPv4'<~String> - IPv4 ip address
|
||||
# * 'accessIPv6'<~String> - IPv6 ip address
|
||||
# * 'progress'<~Integer> - progress through current status
|
||||
# * 'status'<~String> - current server status
|
||||
# * 'created'<~String> - created date time stamp
|
||||
# * 'updated'<~String> - updated date time stamp
|
||||
# * 'user_id'<~String> - user id
|
||||
# * 'tenant_id'<~String> - tenant id
|
||||
# * 'uuid'<~String> - uuid of the server
|
||||
# * 'config_drive'<~String> - config drive
|
||||
# * 'security_groups'<~Array of Hash>
|
||||
# * 'id'<~Integer> - id of the security group
|
||||
# * 'name'<~String> - name of the security group
|
||||
# * 'links'<~Array> - array of security group links
|
||||
# * 'key_name'<~String> - name of the keypair
|
||||
# * 'adminPass'<~String> - admin password for server
|
||||
def create_server(name, flavor_id, image_id, options = {})
|
||||
data = {
|
||||
'server' => {
|
||||
|
@ -81,8 +97,8 @@ module Fog
|
|||
}
|
||||
end
|
||||
end
|
||||
if options['availability_zone']
|
||||
data['server']['availability_zone'] = options['availability_zone']
|
||||
if options['config_drive']
|
||||
data['server']['config_drive'] = options['config_drive']
|
||||
end
|
||||
|
||||
request(
|
||||
|
@ -101,11 +117,11 @@ module Fog
|
|||
response = Excon::Response.new
|
||||
response.status = 202
|
||||
|
||||
#if options['security_groups']
|
||||
# sec_group_name = options['security_groups'][0]
|
||||
#else
|
||||
# sec_group_name = "default"
|
||||
#end
|
||||
if options['security_groups']
|
||||
sec_group_name = options['security_groups'][0]
|
||||
else
|
||||
sec_group_name = "default"
|
||||
end
|
||||
data = {
|
||||
'addresses' => { "private"=>[{"version"=>4, "addr"=>Fog::HP::Mock.ip_address}] },
|
||||
'flavor' => {"id"=>"#{flavor_id}", "links"=>[{"href"=>"http://nova1:8774/admin/flavors/#{flavor_id}", "rel"=>"bookmark"}]},
|
||||
|
@ -125,7 +141,7 @@ module Fog
|
|||
'tenant_id' => Fog::HP::Mock.user_id.to_s,
|
||||
'uuid' => "95253a45-9ead-43c6-90b3-65da2ef048b3",
|
||||
'config_drive' => "",
|
||||
#'security_groups' => [{"name"=>"#{sec_group_name}", "links"=>[{"href"=>"http://nova1:8774/v1.1/admin//os-security-groups/111", "rel"=>"bookmark"}], "id"=>111}],
|
||||
'security_groups' => [{"name"=>"#{sec_group_name}", "links"=>[{"href"=>"http://nova1:8774/v1.1/admin//os-security-groups/111", "rel"=>"bookmark"}], "id"=>111}],
|
||||
'key_name' => options['key_name'] || ""
|
||||
}
|
||||
self.data[:last_modified][:servers][data['id']] = Time.now
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# Delete metadata item for specific collections
|
||||
#
|
||||
# ==== Parameters
|
||||
# * 'collection_name'<~String> - name of the collection i.e. images, servers for which the metadata is intented.
|
||||
# * 'parent_id'<~Integer> - id of the collection i.e. image_id or the server_id
|
||||
# * 'key'<~String> - key for the metadata item
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body: Empty response body
|
||||
#
|
||||
def delete_meta(collection_name, parent_id, key)
|
||||
request(
|
||||
:expects => 204,
|
||||
:method => 'DELETE',
|
||||
:path => "#{collection_name}/#{parent_id}/metadata/#{key}"
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock
|
||||
|
||||
def delete_meta(collection_name, parent_id, key)
|
||||
if collection_name == "images" then
|
||||
if get_image_details(parent_id)
|
||||
self.data[:images][parent_id]['metadata'].delete(key)
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
end
|
||||
|
||||
if collection_name == "servers" then
|
||||
if get_server_details(parent_id)
|
||||
self.data[:servers][parent_id]['metadata'].delete(key)
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
end
|
||||
|
||||
response = Excon::Response.new
|
||||
response.status = 204
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -25,14 +25,14 @@ module Fog
|
|||
response = Excon::Response.new
|
||||
|
||||
sg_rule = nil
|
||||
|
||||
self.data[:security_groups].each do |_, sgv|
|
||||
if sgv['rules']
|
||||
sg_rule_index = sgv['rules'].find_index { |r| !r.nil? && r['id'] == security_group_rule_id }
|
||||
if sg_rule_index
|
||||
sg_rule = sgv['rules'].delete_at sg_rule_index
|
||||
end
|
||||
sg_rule = sgv['rules'].delete_if { |r| !r.nil? && r['id'] == security_group_rule_id }
|
||||
break if sg_rule
|
||||
end
|
||||
end
|
||||
|
||||
if sg_rule && !sg_rule.empty?
|
||||
response.status = 202
|
||||
response.body = "202 Accepted\n\nThe request is accepted for processing.\n\n "
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# Detach a block storage volume from an existing server
|
||||
#
|
||||
# ==== Parameters
|
||||
# * server_id<~Integer> - Id of server to attach the volume to
|
||||
# * volume_id<~Integer> - Id of the volume to be attached to the server
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body: Empty
|
||||
def detach_volume(server_id, volume_id)
|
||||
response = request(
|
||||
:expects => 202,
|
||||
:method => 'DELETE',
|
||||
:path => "servers/#{server_id}/os-volume_attachments/#{volume_id}"
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def detach_volume(server_id, volume_id)
|
||||
response = Excon::Response.new
|
||||
if server = self.data[:servers][server_id]
|
||||
if server['volumeAttachments'] && server['volumeAttachments'].select {|v| v['volumeId'] == volume_id}
|
||||
data = server['volumeAttachments'].reject {|v| v['volumeId'] == volume_id}
|
||||
self.data[:servers][server_id]['volumeAttachments'] = data
|
||||
response.status = 202
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,43 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class HP
|
||||
class Real
|
||||
|
||||
require 'fog/aws/parsers/compute/get_console_output'
|
||||
|
||||
# Retrieve console output for specified instance
|
||||
#
|
||||
# ==== Parameters
|
||||
# * server_id<~Integer> - Id of instance to get console output from
|
||||
# * num_lines<~Integer> - Number of lines of console output from the end
|
||||
# ==== Returns
|
||||
# # * response<~Excon::Response>:
|
||||
# * body<~Hash>:
|
||||
# * 'output'<~String> - Console output
|
||||
#
|
||||
def get_console_output(server_id, num_lines)
|
||||
body = { 'os-getConsoleOutput' => { 'length' => num_lines }}
|
||||
server_action(server_id, body, 200)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock
|
||||
|
||||
def get_console_output(server_id, num_lines)
|
||||
output = ""
|
||||
response = Excon::Response.new
|
||||
if list_servers_detail.body['servers'].detect {|_| _['id'] == server_id}
|
||||
(1..num_lines).each {|i| output += "Console Output Line #{i} \r\n"}
|
||||
response.body = { 'output' => output }
|
||||
response.status = 200
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# Get metadata item for specific collections
|
||||
#
|
||||
# ==== Parameters
|
||||
# * 'collection_name'<~String> - name of the collection i.e. images, servers for which the metadata is intended.
|
||||
# * 'parent_id'<~Integer> - id of the collection i.e. image_id or the server_id
|
||||
# * 'key'<~String> - key for the metadata item
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Hash>:
|
||||
# * meta<~Hash>: hash of key/value pair for the metadata item found
|
||||
#
|
||||
def get_meta(collection_name, parent_id, key)
|
||||
request(
|
||||
:expects => [200, 203],
|
||||
:method => 'GET',
|
||||
:path => "#{collection_name}/#{parent_id}/metadata/#{key}"
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock
|
||||
|
||||
def get_meta(collection_name, parent_id, key)
|
||||
if collection_name == "images" then
|
||||
if get_image_details(parent_id)
|
||||
raise Fog::Compute::HP::NotFound unless midata = self.data[:images][parent_id]['metadata'].fetch(key, nil)
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
end
|
||||
|
||||
if collection_name == "servers" then
|
||||
if get_server_details(parent_id)
|
||||
raise Fog::Compute::HP::NotFound unless midata = self.data[:servers][parent_id]['metadata'].fetch(key, nil)
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
end
|
||||
|
||||
response = Excon::Response.new
|
||||
response.status = 200
|
||||
response.body = { 'meta' => { key => midata } }
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,43 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# Retrieves the encrypted administrator password for a server running Windows.
|
||||
#
|
||||
# ==== Parameters
|
||||
# * server_id<~Integer> - Id of server
|
||||
#
|
||||
# ==== Returns
|
||||
# * password_data<~string>: Encrypted password for a server running Windows
|
||||
#
|
||||
def get_windows_password(server_id)
|
||||
# get console output assuming that the server is already in active state
|
||||
log_output = get_console_output(server_id, 400).body['output']
|
||||
# decrypt the log output to extract the encrypted, base64-encoded password
|
||||
encrypted_password = extract_password_from_log(log_output)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock
|
||||
|
||||
def get_windows_password(server_id)
|
||||
# need to mock out the private key as well
|
||||
private_key = OpenSSL::PKey::RSA.generate(1024)
|
||||
public_key = private_key.public_key
|
||||
### The original password is Passw0rd
|
||||
encoded_password = encrypt_using_public_key("Passw0rd", public_key)
|
||||
|
||||
if list_servers_detail.body['servers'].detect {|_| _['id'] == server_id}
|
||||
# mock output for this call get_console_output(server_id, 400).body['output']
|
||||
log_output = "start junk [cloud-init] Encrypt random password\n-----BEGIN BASE64-ENCODED ENCRYPTED PASSWORD-----\n#{encoded_password}-----END BASE64-ENCODED ENCRYPTED PASSWORD-----\nend junk [cloud-init] Done\n"
|
||||
encrypted_password = extract_password_from_log(log_output)
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,56 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# List metadata for specific collections
|
||||
#
|
||||
# ==== Parameters
|
||||
# * 'collection_name'<~String> - name of the collection i.e. images, servers for which the metadata is intended.
|
||||
# * 'parent_id'<~Integer> - id of the collection i.e. image_id or the server_id
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Hash>:
|
||||
# * metadata<~Hash>: hash of key/value pair for the metadata items found
|
||||
#
|
||||
def list_metadata(collection_name, parent_id)
|
||||
request(
|
||||
:expects => [200, 203],
|
||||
:method => 'GET',
|
||||
:path => "/#{collection_name}/#{parent_id}/metadata.json"
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock
|
||||
|
||||
def list_metadata(collection_name, parent_id)
|
||||
mdata = {}
|
||||
if collection_name == "images" then
|
||||
if get_image_details(parent_id)
|
||||
mdata = self.data[:images][parent_id]['metadata']
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
end
|
||||
|
||||
if collection_name == "servers" then
|
||||
if get_server_details(parent_id)
|
||||
mdata = self.data[:servers][parent_id]['metadata']
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
end
|
||||
|
||||
response = Excon::Response.new
|
||||
response.status = 200
|
||||
response.body = {'metadata' => mdata}
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,49 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# List all volumes attached to a server
|
||||
#
|
||||
# ==== Parameters
|
||||
# * server_id<~Integer> - Id of server to list attached volumes for
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Hash>:
|
||||
# * 'volumeAttachments'<~Array>:
|
||||
# * <~Hash>
|
||||
# * 'device':<~String> - The name of the device
|
||||
# * 'serverId':<~Integer> - The server id to which thsi volume is attached
|
||||
# * 'id':<~Integer> - The volume id
|
||||
# * 'volumeId':<~Integer> - The volume id
|
||||
def list_server_volumes(server_id)
|
||||
response = request(
|
||||
:expects => 200,
|
||||
:method => 'GET',
|
||||
:path => "servers/#{server_id}/os-volume_attachments"
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def list_server_volumes(server_id)
|
||||
response = Excon::Response.new
|
||||
volumes = []
|
||||
if server = self.data[:servers][server_id]
|
||||
volumes = server['volumeAttachments']
|
||||
response.status = 200
|
||||
response.body = { 'volumeAttachments' => volumes }
|
||||
response
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,60 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# Set metadata for specific collections
|
||||
#
|
||||
# ==== Parameters
|
||||
# * 'collection_name'<~String> - name of the collection i.e. images, servers for which the metadata is intented.
|
||||
# * 'parent_id'<~Integer> - id of the collection i.e. image_id or the server_id
|
||||
# * 'metadata'<~Hash> - A hash of key/value pairs containing the metadata
|
||||
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Hash>:
|
||||
# * metadata<~Hash> - key/value pairs of metadata items
|
||||
#
|
||||
def set_metadata(collection_name, parent_id, metadata = {})
|
||||
request(
|
||||
:body => Fog::JSON.encode({ 'metadata' => metadata }),
|
||||
:expects => 200,
|
||||
:method => 'PUT',
|
||||
:path => "#{collection_name}/#{parent_id}/metadata"
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock
|
||||
|
||||
def set_metadata(collection_name, parent_id, metadata = {})
|
||||
|
||||
if collection_name == "images" then
|
||||
if get_image_details(parent_id)
|
||||
self.data[:images][parent_id]['metadata'] = metadata
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
end
|
||||
|
||||
if collection_name == "servers" then
|
||||
if get_server_details(parent_id)
|
||||
self.data[:servers][parent_id]['metadata'] = metadata
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
end
|
||||
|
||||
response = Excon::Response.new
|
||||
response.body = { "metadata" => metadata }
|
||||
response.status = 200
|
||||
response
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,61 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# Set or update metadata item for specific collections
|
||||
#
|
||||
# ==== Parameters
|
||||
# * 'collection_name'<~String> - name of the collection i.e. images, servers for which the metadata is intented.
|
||||
# * 'parent_id'<~Integer> - id of the collection i.e. image_id or the server_id
|
||||
# * 'key'<~String> - key for the metadata item
|
||||
# * 'value'<~String> - value for the metadata item
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Hash>:
|
||||
# * meta<~Hash>: hash of key/value pair for the metadata item updated
|
||||
#
|
||||
def update_meta(collection_name, parent_id, key, value)
|
||||
request(
|
||||
:body => Fog::JSON.encode({ 'meta' => { key => value }}),
|
||||
:expects => 200,
|
||||
:method => 'PUT',
|
||||
:path => "#{collection_name}/#{parent_id}/metadata/#{key}"
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock
|
||||
|
||||
def update_meta(collection_name, parent_id, key, value)
|
||||
|
||||
if collection_name == "images" then
|
||||
if get_image_details(parent_id)
|
||||
self.data[:images][parent_id]['metadata'][key] = value
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
end
|
||||
|
||||
if collection_name == "servers" then
|
||||
if get_server_details(parent_id)
|
||||
self.data[:servers][parent_id]['metadata'][key] = value
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
end
|
||||
|
||||
response = Excon::Response.new
|
||||
response.body = { "meta" => { key => value } }
|
||||
response.status = 200
|
||||
response
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,60 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# Update metadata for specific collections
|
||||
#
|
||||
# ==== Parameters
|
||||
# * 'collection_name'<~String> - name of the collection i.e. images, servers for which the metadata is intented.
|
||||
# * 'parent_id'<~Integer> - id of the collection i.e. image_id or the server_id
|
||||
# * 'metadata'<~Hash> - A hash of key/value pairs containing the metadata
|
||||
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Hash>:
|
||||
# * metadata<~Hash> - all key/value pairs of metadata items merged with existing metadata
|
||||
#
|
||||
def update_metadata(collection_name, parent_id, metadata = {})
|
||||
request(
|
||||
:body => Fog::JSON.encode({ 'metadata' => metadata }),
|
||||
:expects => 200,
|
||||
:method => 'POST',
|
||||
:path => "#{collection_name}/#{parent_id}/metadata.json"
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock
|
||||
|
||||
def update_metadata(collection_name, parent_id, metadata = {})
|
||||
|
||||
if collection_name == "images" then
|
||||
if get_image_details(parent_id)
|
||||
newmetadata = self.data[:images][parent_id]['metadata'].merge!(metadata)
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
end
|
||||
|
||||
if collection_name == "servers" then
|
||||
if get_server_details(parent_id)
|
||||
newmetadata = self.data[:servers][parent_id]['metadata'].merge!(metadata)
|
||||
else
|
||||
raise Fog::Compute::HP::NotFound
|
||||
end
|
||||
end
|
||||
|
||||
response = Excon::Response.new
|
||||
response.body = { "metadata" => newmetadata }
|
||||
response.status = 200
|
||||
response
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,38 @@
|
|||
module Fog
|
||||
module Storage
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# Delete a shared object
|
||||
#
|
||||
# ==== Parameters
|
||||
# * shared_object_url<~String> - Url of the shared object
|
||||
#
|
||||
def delete_shared_object(shared_object_url)
|
||||
# split up the shared object url
|
||||
uri = URI.parse(shared_object_url)
|
||||
path = uri.path
|
||||
|
||||
response = shared_request(
|
||||
:expects => 204,
|
||||
:method => 'DELETE',
|
||||
:path => path
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def delete_shared_object(shared_object_url)
|
||||
response = Excon::Response.new
|
||||
response.status = 204
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -10,18 +10,21 @@ module Fog
|
|||
# * object<~String> - Name of object to look for
|
||||
#
|
||||
def get_object(container, object, &block)
|
||||
params = {}
|
||||
|
||||
if block_given?
|
||||
params[:response_block] = Proc.new
|
||||
response = request(
|
||||
:response_block => block,
|
||||
:expects => 200,
|
||||
:method => 'GET',
|
||||
:path => "#{Fog::HP.escape(container)}/#{Fog::HP.escape(object)}"
|
||||
)
|
||||
else
|
||||
response = request({
|
||||
:block => block,
|
||||
:expects => 200,
|
||||
:method => 'GET',
|
||||
:path => "#{Fog::HP.escape(container)}/#{Fog::HP.escape(object)}"
|
||||
}, false, &block)
|
||||
end
|
||||
|
||||
response = request(params.merge!({
|
||||
:block => block,
|
||||
:expects => 200,
|
||||
:method => 'GET',
|
||||
:path => "#{Fog::HP.escape(container)}/#{Fog::HP.escape(object)}"
|
||||
}), false)
|
||||
response
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
module Fog
|
||||
module Storage
|
||||
class HP
|
||||
|
||||
class Real
|
||||
|
||||
# Generate a temporary url for an object
|
||||
#
|
||||
# ==== Parameters
|
||||
# * container<~String> - Name of container
|
||||
# * object<~String> - Name of object
|
||||
# * expires<~Integer> - Time the temporary url expire in secs.
|
||||
# * method<~String> - Allowed HTTP method GET, PUT, HEAD only
|
||||
def get_object_temp_url(container, object, expires, method)
|
||||
generate_object_temp_url(container, object, expires, method)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def get_object_temp_url(container, object, expires, method)
|
||||
@hp_storage_uri = "https://swift-cluster.example.com:443/v1/account"
|
||||
|
||||
generate_object_temp_url(container, object, expires, method)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,75 @@
|
|||
module Fog
|
||||
module Storage
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# Get details for a shared container
|
||||
#
|
||||
# ==== Parameters
|
||||
# * shared_container_url<~String> - Url of the shared container
|
||||
# * options<~String>:
|
||||
# * 'limit'<~String> - Maximum number of objects to return
|
||||
# * 'marker'<~String> - Only return objects whose name is greater than marker
|
||||
# * 'prefix'<~String> - Limits results to those starting with prefix
|
||||
# * 'path'<~String> - Return objects nested in the pseudo path
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * headers<~Hash>:
|
||||
# * 'X-Container-Object-Count'<~String> - Count of objects in container
|
||||
# * 'X-Container-Bytes-Used'<~String> - Bytes used
|
||||
# * 'X-Trans-Id'<~String> - Trans Id
|
||||
# * body<~Array>:
|
||||
# * item<~Hash>:
|
||||
# * 'bytes'<~String> - Size of object
|
||||
# * 'content_type'<~String> Content-Type of object
|
||||
# * 'hash'<~String> - Hash of object (etag?)
|
||||
# * 'last_modified'<~String> - Last modified timestamp
|
||||
# * 'name'<~String> - Name of object
|
||||
def get_shared_container(shared_container_url, options = {})
|
||||
options = options.reject {|key, value| value.nil?}
|
||||
# split up the shared container url
|
||||
uri = URI.parse(shared_container_url)
|
||||
path = uri.path
|
||||
|
||||
response = shared_request(
|
||||
:expects => 200,
|
||||
:method => 'GET',
|
||||
:path => path,
|
||||
:query => {'format' => 'json'}.merge!(options)
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def get_shared_container(shared_container_url, options = {})
|
||||
response = Excon::Response.new
|
||||
data = {
|
||||
'name' => Fog::Mock.random_letters(10),
|
||||
'hash' => Fog::HP::Mock.etag,
|
||||
'bytes' => 11,
|
||||
'content_type' => "text/plain",
|
||||
'last_modified' => Time.now
|
||||
}
|
||||
response.status = 200
|
||||
response.body = [data]
|
||||
response.headers = {
|
||||
'X-Container-Object-Count' => 1,
|
||||
'X-Container-Bytes-Used' => 11,
|
||||
'Accept-Ranges' => 'bytes',
|
||||
'Content-Type' => "application/json",
|
||||
'Content-Length' => 11,
|
||||
'X-Trans-Id' => "tx#{Fog::Mock.random_hex(32)}"
|
||||
}
|
||||
response
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,67 @@
|
|||
module Fog
|
||||
module Storage
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# Get details for a shared object
|
||||
#
|
||||
# ==== Parameters
|
||||
# * shared_object_url<~String> - Url of the shared object
|
||||
#
|
||||
def get_shared_object(shared_object_url, &block)
|
||||
# split up the shared object url
|
||||
uri = URI.parse(shared_object_url)
|
||||
path = uri.path
|
||||
|
||||
if block_given?
|
||||
response = shared_request(
|
||||
:response_block => block,
|
||||
:expects => 200,
|
||||
:method => 'GET',
|
||||
:path => path
|
||||
)
|
||||
else
|
||||
response = shared_request({
|
||||
:block => block,
|
||||
:expects => 200,
|
||||
:method => 'GET',
|
||||
:path => path
|
||||
}, false, &block)
|
||||
end
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def get_shared_object(shared_object_url, &block)
|
||||
response = Excon::Response.new
|
||||
response.status = 200
|
||||
response.headers = {
|
||||
'Last-Modified' => Date.today.rfc822,
|
||||
'Etag' => Fog::HP::Mock.etag,
|
||||
'Accept-Ranges' => 'bytes',
|
||||
'Content-Type' => "text/plain",
|
||||
'Content-Length' => 11,
|
||||
'X-Trans-Id' => "tx#{Fog::Mock.random_hex(32)}"
|
||||
}
|
||||
unless block_given?
|
||||
response.body = "This is a sample text.\n"
|
||||
else
|
||||
data = StringIO.new("This is a sample text.\n")
|
||||
remaining = data.length
|
||||
while remaining > 0
|
||||
chunk = data.read([remaining, Excon::CHUNK_SIZE].min)
|
||||
block.call(chunk)
|
||||
remaining -= Excon::CHUNK_SIZE
|
||||
end
|
||||
end
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -30,6 +30,7 @@ module Fog
|
|||
def head_container(container_name)
|
||||
response = get_container(container_name)
|
||||
response.body = nil
|
||||
response.status = 204
|
||||
response
|
||||
end
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ module Fog
|
|||
def head_object(container_name, object_name, options = {})
|
||||
response = get_object(container_name, object_name, options)
|
||||
response.body = nil
|
||||
response.status = 200
|
||||
response
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
module Fog
|
||||
module Storage
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# List number of objects and total bytes stored for a shared container
|
||||
#
|
||||
# ==== Parameters
|
||||
# * shared_container_url<~String> - Url of the shared container
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * headers<~Hash>:
|
||||
# * 'X-Container-Object-Count'<~String> - Count of containers
|
||||
# * 'X-Container-Bytes-Used'<~String> - Bytes used
|
||||
def head_shared_container(shared_container_url)
|
||||
# split up the shared container url
|
||||
uri = URI.parse(shared_container_url)
|
||||
path = uri.path
|
||||
|
||||
response = shared_request(
|
||||
:expects => 204,
|
||||
:method => 'HEAD',
|
||||
:path => path,
|
||||
:query => {'format' => 'json'}
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def head_shared_container(shared_container_url)
|
||||
response = get_shared_container(shared_container_url)
|
||||
response.body = nil
|
||||
response.status = 204
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,39 @@
|
|||
module Fog
|
||||
module Storage
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# Get headers for shared object
|
||||
#
|
||||
# ==== Parameters
|
||||
# * * shared_object_url<~String> - Url of the shared object
|
||||
#
|
||||
def head_shared_object(shared_object_url)
|
||||
# split up the shared object url
|
||||
uri = URI.parse(shared_object_url)
|
||||
path = uri.path
|
||||
|
||||
response = shared_request({
|
||||
:expects => 200,
|
||||
:method => 'HEAD',
|
||||
:path => path
|
||||
}, false)
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def head_shared_object(shared_object_url)
|
||||
response = get_shared_object(shared_object_url)
|
||||
response.body = nil
|
||||
response.status = 200
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -22,16 +22,16 @@ module Fog
|
|||
|
||||
class Mock # :nodoc:all
|
||||
def put_container(container_name, options = {})
|
||||
acl = options['X-Container-Read'] || 'private'
|
||||
if !['private', 'public-read'].include?(acl)
|
||||
#raise Excon::Errors::BadRequest.new('invalid X-Container-Read')
|
||||
else
|
||||
self.data[:acls][:container][container_name] = self.class.acls(acl)
|
||||
read_h = options['X-Container-Read'] || ''
|
||||
write_h = options['X-Container-Write'] || ''
|
||||
unless options
|
||||
read_acl, write_acl = self.class.header_to_perm_acl(read_h, write_h)
|
||||
self.data[:acls][:container][container_name] = {:read_acl => read_acl, :write_acl => write_acl}
|
||||
end
|
||||
|
||||
response = Excon::Response.new
|
||||
container = {
|
||||
:objects => {},
|
||||
:objects => {}
|
||||
}
|
||||
if self.data[:containers][container_name]
|
||||
response.status = 202
|
||||
|
|
|
@ -8,9 +8,20 @@ module Fog
|
|||
# ==== Parameters
|
||||
# * container<~String> - Name for container, should be < 256 bytes and must not contain '/'
|
||||
#
|
||||
def put_object(container, object, data, options = {})
|
||||
def put_object(container, object, data, options = {}, &block)
|
||||
data = Fog::Storage.parse_data(data)
|
||||
headers = data[:headers].merge!(options)
|
||||
if block_given?
|
||||
headers['Transfer-Encoding'] = 'chunked'
|
||||
headers.delete('Content-Length')
|
||||
return request(
|
||||
:request_block => block,
|
||||
:expects => 201,
|
||||
:headers => headers,
|
||||
:method => 'PUT',
|
||||
:path => "#{Fog::HP.escape(container)}/#{Fog::HP.escape(object)}"
|
||||
)
|
||||
end
|
||||
if headers.has_key?('Transfer-Encoding')
|
||||
headers.delete('Content-Length')
|
||||
end
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
module Fog
|
||||
module Storage
|
||||
class HP
|
||||
class Real
|
||||
|
||||
# Create a new object in a shared container
|
||||
#
|
||||
# ==== Parameters
|
||||
# * shared_container_url<~String> - Shared url for the container
|
||||
# * object<~String> - Name of the object
|
||||
# * options<~Hash> - header options
|
||||
#
|
||||
def put_shared_object(shared_container_url, object_name, data, options = {}, &block)
|
||||
# split up the shared object url
|
||||
uri = URI.parse(shared_container_url)
|
||||
path = uri.path
|
||||
|
||||
data = Fog::Storage.parse_data(data)
|
||||
headers = data[:headers].merge!(options)
|
||||
if block_given?
|
||||
headers['Transfer-Encoding'] = 'chunked'
|
||||
headers.delete('Content-Length')
|
||||
return shared_request(
|
||||
:request_block => block,
|
||||
:expects => 201,
|
||||
:headers => headers,
|
||||
:method => 'PUT',
|
||||
:path => "#{path}/#{Fog::HP.escape(object_name)}"
|
||||
)
|
||||
end
|
||||
if headers.has_key?('Transfer-Encoding')
|
||||
headers.delete('Content-Length')
|
||||
end
|
||||
response = shared_request(
|
||||
:body => data[:body],
|
||||
:expects => 201,
|
||||
:headers => headers,
|
||||
:method => 'PUT',
|
||||
:path => "#{path}/#{Fog::HP.escape(object_name)}"
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def put_shared_object(shared_container_url, object_name, data, options = {}, &block)
|
||||
response = Excon::Response.new
|
||||
data = Fog::Storage.parse_data(data)
|
||||
unless data[:body].is_a?(String)
|
||||
data[:body] = data[:body].read
|
||||
end
|
||||
response.status = 201
|
||||
object = {
|
||||
:body => data[:body],
|
||||
'Content-Type' => options['Content-Type'] || data[:headers]['Content-Type'],
|
||||
'ETag' => Fog::HP::Mock.etag,
|
||||
'Key' => object_name,
|
||||
'Date' => Fog::Time.now.to_date_header,
|
||||
'Content-Length' => options['Content-Length'] || data[:headers]['Content-Length'],
|
||||
}
|
||||
|
||||
for key, value in options
|
||||
case key
|
||||
when 'Cache-Control', 'Content-Disposition', 'Content-Encoding', 'Content-MD5', 'Expires', /^X-Object-Meta-/
|
||||
object[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
response.headers = {
|
||||
'Content-Length' => object['Content-Length'],
|
||||
'Content-Type' => object['Content-Type'],
|
||||
'ETag' => object['ETag'],
|
||||
'Date' => object['Date']
|
||||
}
|
||||
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5,28 +5,42 @@ module Fog
|
|||
module Storage
|
||||
class HP < Fog::Service
|
||||
|
||||
requires :hp_secret_key, :hp_account_id, :hp_tenant_id
|
||||
recognizes :hp_auth_uri, :hp_servicenet, :hp_cdn_ssl, :hp_cdn_uri, :persistent, :connection_options, :hp_use_upass_auth_style, :hp_auth_version
|
||||
requires :hp_secret_key, :hp_tenant_id, :hp_avl_zone
|
||||
recognizes :hp_auth_uri, :hp_cdn_ssl, :hp_cdn_uri
|
||||
recognizes :persistent, :connection_options
|
||||
recognizes :hp_use_upass_auth_style, :hp_auth_version, :user_agent
|
||||
recognizes :hp_access_key, :hp_account_id # :hp_account_id is deprecated use hp_access_key instead
|
||||
|
||||
secrets :hp_secret_key
|
||||
|
||||
model_path 'fog/hp/models/storage'
|
||||
model :directory
|
||||
collection :directories
|
||||
model :shared_directory
|
||||
collection :shared_directories
|
||||
model :file
|
||||
collection :files
|
||||
model :shared_file
|
||||
collection :shared_files
|
||||
|
||||
request_path 'fog/hp/requests/storage'
|
||||
request :delete_container
|
||||
request :delete_object
|
||||
request :delete_shared_object
|
||||
request :get_container
|
||||
request :get_containers
|
||||
request :get_object
|
||||
request :get_object_temp_url
|
||||
request :get_shared_container
|
||||
request :get_shared_object
|
||||
request :head_container
|
||||
request :head_containers
|
||||
request :head_object
|
||||
request :head_shared_container
|
||||
request :head_shared_object
|
||||
request :put_container
|
||||
request :put_object
|
||||
request :put_shared_object
|
||||
|
||||
module Utils
|
||||
|
||||
|
@ -34,11 +48,12 @@ module Fog
|
|||
unless @hp_cdn_uri.nil?
|
||||
@cdn ||= Fog::CDN.new(
|
||||
:provider => 'HP',
|
||||
:hp_account_id => @hp_account_id,
|
||||
:hp_access_key => @hp_access_key,
|
||||
:hp_secret_key => @hp_secret_key,
|
||||
:hp_auth_uri => @hp_auth_uri,
|
||||
:hp_cdn_uri => @hp_cdn_uri,
|
||||
:hp_tenant_id => @hp_tenant_id,
|
||||
:hp_avl_zone => @hp_avl_zone,
|
||||
:connection_options => @connection_options
|
||||
)
|
||||
if @cdn.enabled?
|
||||
|
@ -53,35 +68,118 @@ module Fog
|
|||
"#{@scheme}://#{@host}:#{@port}#{@path}"
|
||||
end
|
||||
|
||||
def acl_to_header(acl)
|
||||
def public_url(container=nil, object=nil)
|
||||
public_url = nil
|
||||
unless container.nil?
|
||||
if object.nil?
|
||||
# return container public url
|
||||
public_url = "#{url}/#{Fog::HP.escape(container)}"
|
||||
else
|
||||
# return object public url
|
||||
public_url = "#{url}/#{Fog::HP.escape(container)}/#{Fog::HP.escape(object)}"
|
||||
end
|
||||
end
|
||||
public_url
|
||||
end
|
||||
|
||||
def perm_to_acl(perm, users=[])
|
||||
read_perm_acl = []
|
||||
write_perm_acl = []
|
||||
valid_public_perms = ['pr', 'pw', 'prw']
|
||||
valid_account_perms = ['r', 'w', 'rw']
|
||||
valid_perms = valid_public_perms + valid_account_perms
|
||||
unless valid_perms.include?(perm)
|
||||
raise ArgumentError.new("permission must be one of [#{valid_perms.join(', ')}]")
|
||||
end
|
||||
# tackle the public access differently
|
||||
if valid_public_perms.include?(perm)
|
||||
case perm
|
||||
when "pr"
|
||||
read_perm_acl = [".r:*",".rlistings"]
|
||||
when "pw"
|
||||
write_perm_acl = ["*"]
|
||||
when "prw"
|
||||
read_perm_acl = [".r:*",".rlistings"]
|
||||
write_perm_acl = ["*"]
|
||||
end
|
||||
elsif valid_account_perms.include?(perm)
|
||||
# tackle the user access differently
|
||||
unless (users.nil? || users.empty?)
|
||||
# return the correct acls
|
||||
tenant_id = "*" # this might change later
|
||||
acl_array = users.map { |u| "#{tenant_id}:#{u}" }
|
||||
#acl_string = acl_array.join(',')
|
||||
case perm
|
||||
when "r"
|
||||
read_perm_acl = acl_array
|
||||
when "w"
|
||||
write_perm_acl = acl_array
|
||||
when "rw"
|
||||
read_perm_acl = acl_array
|
||||
write_perm_acl = acl_array
|
||||
end
|
||||
end
|
||||
end
|
||||
return read_perm_acl, write_perm_acl
|
||||
end
|
||||
|
||||
def perm_acl_to_header(read_perm_acl, write_perm_acl)
|
||||
header = {}
|
||||
case acl
|
||||
when "private"
|
||||
header['X-Container-Read'] = ""
|
||||
header['X-Container-Write'] = ""
|
||||
when "public-read"
|
||||
header['X-Container-Read'] = ".r:*,.rlistings"
|
||||
when "public-write"
|
||||
header['X-Container-Write'] = "*"
|
||||
when "public-read-write"
|
||||
header['X-Container-Read'] = ".r:*,.rlistings"
|
||||
header['X-Container-Write'] = "*"
|
||||
if read_perm_acl.nil? && write_perm_acl.nil?
|
||||
header = {'X-Container-Read' => "", 'X-Container-Write' => ""}
|
||||
elsif !read_perm_acl.nil? && write_perm_acl.nil?
|
||||
header = {'X-Container-Read' => "#{read_perm_acl.join(',')}", 'X-Container-Write' => ""}
|
||||
elsif read_perm_acl.nil? && !write_perm_acl.nil?
|
||||
header = {'X-Container-Read' => "", 'X-Container-Write' => "#{write_perm_acl.join(',')}"}
|
||||
elsif !read_perm_acl.nil? && !write_perm_acl.nil?
|
||||
header = {'X-Container-Read' => "#{read_perm_acl.join(',')}", 'X-Container-Write' => "#{write_perm_acl.join(',')}"}
|
||||
end
|
||||
header
|
||||
end
|
||||
|
||||
def header_to_acl(read_header=nil, write_header=nil)
|
||||
acl = nil
|
||||
if read_header.nil? && write_header.nil?
|
||||
acl = nil
|
||||
elsif !read_header.nil? && read_header.include?(".r:*") && write_header.nil?
|
||||
acl = "public-read"
|
||||
elsif !write_header.nil? && write_header.include?("*") && read_header.nil?
|
||||
acl = "public-write"
|
||||
elsif !read_header.nil? && read_header.include?(".r:*") && !write_header.nil? && write_header.include?("*")
|
||||
acl = "public-read-write"
|
||||
end
|
||||
def header_to_perm_acl(read_header=nil, write_header=nil)
|
||||
read_h, write_h = nil
|
||||
read_h = read_header.split(',') unless read_header.nil?
|
||||
write_h = write_header.split(',') unless write_header.nil?
|
||||
return read_h, write_h
|
||||
end
|
||||
|
||||
def generate_object_temp_url(container, object, expires_secs, method)
|
||||
return unless (container && object && expires_secs && method)
|
||||
|
||||
# POST not allowed
|
||||
allowed_methods = %w{GET PUT HEAD}
|
||||
unless allowed_methods.include?(method)
|
||||
raise ArgumentError.new("Invalid method '#{method}' specified. Valid methods are: #{allowed_methods.join(', ')}")
|
||||
end
|
||||
|
||||
expires = (Time.now + expires_secs.to_i).to_i
|
||||
|
||||
# split up the storage uri
|
||||
uri = URI.parse(@hp_storage_uri)
|
||||
host = uri.host
|
||||
path = uri.path
|
||||
port = uri.port
|
||||
scheme = uri.scheme
|
||||
|
||||
# do not encode before signature generation, encode after
|
||||
sig_path = "#{path}/#{container}/#{object}"
|
||||
encoded_path = "#{path}/#{Fog::HP.escape(container)}/#{Fog::HP.escape(object)}"
|
||||
|
||||
string_to_sign = "#{method}\n#{expires}\n#{sig_path}"
|
||||
# Only works with 1.9+ Not compatible with 1.8.7
|
||||
#signed_string = Digest::HMAC.hexdigest(string_to_sign, @hp_secret_key, Digest::SHA1)
|
||||
# Compatible with 1.8.7 onwards
|
||||
hmac = OpenSSL::HMAC.new(@hp_secret_key, OpenSSL::Digest::SHA1.new)
|
||||
signed_string = hmac.update(string_to_sign).hexdigest
|
||||
|
||||
signature = @hp_tenant_id.to_s + ":" + @hp_access_key.to_s + ":" + signed_string
|
||||
signature = Fog::HP.escape(signature)
|
||||
|
||||
# generate the temp url using the signature and expiry
|
||||
temp_url = "#{scheme}://#{host}:#{port}#{encoded_path}?temp_url_sig=#{signature}&temp_url_expires=#{expires}"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock
|
||||
|
@ -108,16 +206,25 @@ module Fog
|
|||
|
||||
def initialize(options={})
|
||||
require 'mime/types'
|
||||
# deprecate hp_account_id
|
||||
if options[:hp_account_id]
|
||||
Fog::Logger.deprecation(":hp_account_id is deprecated, please use :hp_access_key instead.")
|
||||
@hp_access_key = options.delete(:hp_account_id)
|
||||
end
|
||||
@hp_access_key = options[:hp_access_key]
|
||||
unless @hp_access_key
|
||||
raise ArgumentError.new("Missing required arguments: hp_access_key. :hp_account_id is deprecated, please use :hp_access_key instead.")
|
||||
end
|
||||
@hp_secret_key = options[:hp_secret_key]
|
||||
@hp_account_id = options[:hp_account_id]
|
||||
@hp_tenant_id = options[:hp_tenant_id]
|
||||
end
|
||||
|
||||
def data
|
||||
self.class.data[@hp_account_id]
|
||||
self.class.data[@hp_access_key]
|
||||
end
|
||||
|
||||
def reset_data
|
||||
self.class.data.delete(@hp_account_id)
|
||||
self.class.data.delete(@hp_access_key)
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -128,16 +235,25 @@ module Fog
|
|||
|
||||
def initialize(options={})
|
||||
require 'mime/types'
|
||||
# deprecate hp_account_id
|
||||
if options[:hp_account_id]
|
||||
Fog::Logger.deprecation(":hp_account_id is deprecated, please use :hp_access_key instead.")
|
||||
options[:hp_access_key] = options.delete(:hp_account_id)
|
||||
end
|
||||
@hp_access_key = options[:hp_access_key]
|
||||
unless @hp_access_key
|
||||
raise ArgumentError.new("Missing required arguments: hp_access_key. :hp_account_id is deprecated, please use :hp_access_key instead.")
|
||||
end
|
||||
@hp_secret_key = options[:hp_secret_key]
|
||||
@hp_account_id = options[:hp_account_id]
|
||||
@hp_auth_uri = options[:hp_auth_uri]
|
||||
@hp_cdn_ssl = options[:hp_cdn_ssl]
|
||||
@connection_options = options[:connection_options] || {}
|
||||
### Set an option to use the style of authentication desired; :v1 or :v2 (default)
|
||||
auth_version = options[:hp_auth_version] || :v2
|
||||
### Pass the service type for object storage to the authentication call
|
||||
options[:hp_service_type] = "object-store"
|
||||
### Pass the service name for object storage to the authentication call
|
||||
options[:hp_service_type] = "Object Storage"
|
||||
@hp_tenant_id = options[:hp_tenant_id]
|
||||
@hp_avl_zone = options[:hp_avl_zone]
|
||||
|
||||
### Make the authentication call
|
||||
if (auth_version == :v2)
|
||||
|
@ -157,12 +273,11 @@ module Fog
|
|||
@auth_token = credentials[:auth_token]
|
||||
|
||||
uri = URI.parse(@hp_storage_uri)
|
||||
@host = options[:hp_servicenet] == true ? "snet-#{uri.host}" : uri.host
|
||||
@host = uri.host
|
||||
@path = uri.path
|
||||
@persistent = options[:persistent] || false
|
||||
@port = uri.port
|
||||
@scheme = uri.scheme
|
||||
Excon.ssl_verify_peer = false if options[:hp_servicenet] == true
|
||||
|
||||
@connection = Fog::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
|
||||
end
|
||||
|
@ -195,6 +310,33 @@ module Fog
|
|||
response
|
||||
end
|
||||
|
||||
# this request is used only for get_shared_container and get_shared_object calls
|
||||
def shared_request(params, parse_json = true, &block)
|
||||
begin
|
||||
response = @connection.request(params.merge!({
|
||||
:headers => {
|
||||
'Content-Type' => 'application/json',
|
||||
'X-Auth-Token' => @auth_token
|
||||
}.merge!(params[:headers] || {}),
|
||||
:host => @host,
|
||||
:path => "#{params[:path]}",
|
||||
}), &block)
|
||||
rescue Excon::Errors::HTTPStatusError => error
|
||||
raise case error
|
||||
when Excon::Errors::NotFound
|
||||
Fog::Storage::HP::NotFound.slurp(error)
|
||||
when Excon::Errors::Forbidden
|
||||
Fog::HP::Errors::Forbidden.slurp(error)
|
||||
else
|
||||
error
|
||||
end
|
||||
end
|
||||
if !response.body.empty? && parse_json && response.headers['Content-Type'] =~ %r{application/json}
|
||||
response.body = Fog::JSON.decode(response.body)
|
||||
end
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,4 +30,4 @@ require 'fog/vmfusion'
|
|||
require 'fog/vsphere'
|
||||
require 'fog/voxel'
|
||||
require 'fog/xenserver'
|
||||
require 'fog/zerigo'
|
||||
require 'fog/zerigo'
|
|
@ -91,6 +91,14 @@ def compute_providers
|
|||
:joyent => {
|
||||
:mocked => false
|
||||
},
|
||||
:hp => {
|
||||
:server_attributes => {
|
||||
:flavor_id => 100,
|
||||
:image_id => 1242,
|
||||
:name => "fog_#{Time.now.to_i}"
|
||||
},
|
||||
:mocked => true
|
||||
},
|
||||
:ninefold => {
|
||||
:mocked => false
|
||||
},
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
Shindo.tests('Fog::Connection', 'core') do
|
||||
tests('user_agent').returns("fog/#{Fog::VERSION}") do
|
||||
conn = Fog::Connection.new("http://www.testserviceurl.com", false, {})
|
||||
conn.instance_variable_get(:@excon).connection[:headers]['User-Agent']
|
||||
end
|
||||
end
|
|
@ -39,9 +39,10 @@ if Fog.mock?
|
|||
:go_grid_shared_secret => 'go_grid_shared_secret',
|
||||
:google_storage_access_key_id => 'google_storage_access_key_id',
|
||||
:google_storage_secret_access_key => 'google_storage_secret_access_key',
|
||||
:hp_account_id => 'hp_account_id',
|
||||
:hp_access_key => 'hp_access_key',
|
||||
:hp_secret_key => 'hp_secret_key',
|
||||
:hp_tenant_id => 'hp_tenant_id',
|
||||
:hp_avl_zone => 'hp_avl_zone',
|
||||
:ibm_username => 'ibm_username',
|
||||
:ibm_password => 'ibm_password',
|
||||
:joyent_username => "joyentuser",
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
Shindo.tests("HP::BlockStorage | bootable volumes", ['hp', 'block_storage', 'volumes']) do
|
||||
|
||||
@base_image_id = ENV["BASE_IMAGE_ID"] || 1242
|
||||
|
||||
model_tests(HP[:block_storage].bootable_volumes, {:name => "fogbvoltests", :description => "fogbvoltests-desc", :size => 10, :image_id => @base_image_id}, true)
|
||||
|
||||
tests("new volume") do
|
||||
@volume = HP[:block_storage].bootable_volumes.create(:name => "testbvol", :size => 10, :image_id => @base_image_id)
|
||||
@volume.wait_for { ready? } unless Fog.mocking?
|
||||
|
||||
test("get(#{@volume.id})") do
|
||||
HP[:block_storage].bootable_volumes.get(@volume.id) != nil?
|
||||
end
|
||||
|
||||
test("has_attachments?") do
|
||||
@volume.has_attachments? == false
|
||||
end
|
||||
after do
|
||||
@volume.destroy
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
Shindo.tests("HP::BlockStorage | snapshots", ['hp', 'block_storage', 'snapshots']) do
|
||||
|
||||
@volume = HP[:block_storage].volumes.create(:name => "testsnapvol", :size => 1)
|
||||
@volume.wait_for { ready? } unless Fog.mocking?
|
||||
|
||||
model_tests(HP[:block_storage].snapshots, {:name => "fogsnaptests", :description => "fogsnaptests-desc", :volume_id => @volume.id}, true)
|
||||
|
||||
tests("new snapshot") do
|
||||
@snapshot = HP[:block_storage].snapshots.create(:name => "testvol", :volume_id => @volume.id)
|
||||
@snapshot.wait_for { ready? } unless Fog.mocking?
|
||||
|
||||
test("get(#{@snapshot.id})") do
|
||||
HP[:block_storage].snapshots.get(@snapshot.id) != nil?
|
||||
end
|
||||
|
||||
after do
|
||||
@snapshot.destroy
|
||||
end
|
||||
end
|
||||
|
||||
@volume.destroy
|
||||
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
Shindo.tests("HP::BlockStorage | volumes", ['hp', 'block_storage', 'volumes']) do
|
||||
|
||||
model_tests(HP[:block_storage].volumes, {:name => "fogvoltests", :description => "fogvoltests-desc", :size => 1}, true)
|
||||
|
||||
tests("new volume") do
|
||||
@volume = HP[:block_storage].volumes.create(:name => "testvol", :size => 1)
|
||||
@volume.wait_for { ready? } unless Fog.mocking?
|
||||
|
||||
test("get(#{@volume.id})") do
|
||||
HP[:block_storage].volumes.get(@volume.id) != nil?
|
||||
end
|
||||
|
||||
test("has_attachments?") do
|
||||
@volume.has_attachments? == false
|
||||
end
|
||||
after do
|
||||
@volume.destroy
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
Shindo.tests("Fog::Compute[:hp] | address", ["hp"]) do
|
||||
Shindo.tests("Fog::Compute[:hp] | address", ['hp']) do
|
||||
|
||||
@base_image_id = ENV["BASE_IMAGE_ID"] || 1242
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Shindo.tests("Fog::Compute[:hp] | addresses", ["hp"]) do
|
||||
Shindo.tests("Fog::Compute[:hp] | addresses", ['hp']) do
|
||||
|
||||
collection_tests(Fog::Compute[:hp].addresses, {}, true)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Shindo.tests("Fog::Compute[:hp] | key_pair", ["hp"]) do
|
||||
Shindo.tests("Fog::Compute[:hp] | key_pair", ['hp']) do
|
||||
|
||||
model_tests(Fog::Compute[:hp].key_pairs, {:name => 'fogkeyname'}, true)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Shindo.tests("Fog::Compute[:hp] | key_pairs", ["hp"]) do
|
||||
Shindo.tests("Fog::Compute[:hp] | key_pairs", ['hp']) do
|
||||
|
||||
collection_tests(Fog::Compute[:hp].key_pairs, {:name => 'fogkeyname'}, true)
|
||||
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
Shindo.tests("Fog::Compute[:hp] | metadata for images", ['hp']) do
|
||||
|
||||
@base_image_id = ENV["BASE_IMAGE_ID"] || 1242
|
||||
|
||||
@server = Fog::Compute[:hp].servers.create(:name => "fogsermdtests", :flavor_id => 100, :image_id => @base_image_id)
|
||||
@server.wait_for { ready? }
|
||||
response = @server.create_image("fogimgmetadatatests", :metadata => {'Meta1' => 'MetaValue1', 'Meta2' => 'MetaValue2'})
|
||||
unless Fog.mocking?
|
||||
sleep(10)
|
||||
end
|
||||
new_image_id = response.headers["Location"].split("/")[5]
|
||||
@image = Fog::Compute[:hp].images.get(new_image_id)
|
||||
tests('success') do
|
||||
|
||||
tests("#all").succeeds do
|
||||
@image.metadata.all
|
||||
end
|
||||
|
||||
tests("#get('Meta1')").succeeds do
|
||||
pending if Fog.mocking?
|
||||
@image.metadata.get('Meta1')
|
||||
end
|
||||
|
||||
tests("#update({'Meta3' => 'MetaValue3'})").succeeds do
|
||||
@data = @image.metadata.update({'Meta3' => 'MetaValue3'})
|
||||
test("metadata has updated correctly") do
|
||||
@image.metadata.get('Meta3').value == "MetaValue3"
|
||||
end
|
||||
end
|
||||
|
||||
tests("#set({'Meta4' => 'MetaValue4'})").succeeds do
|
||||
@data = @image.metadata.set({'Meta4' => 'MetaValue4'})
|
||||
test("metadata has set correctly") do
|
||||
@image.metadata.get('Meta4').value == "MetaValue4"
|
||||
end
|
||||
end
|
||||
|
||||
tests("#save").succeeds do
|
||||
m = @image.metadata.new(:key => 'Meta5', :value => 'MetaValue5')
|
||||
@data = m.save
|
||||
test("metadata has saved correctly") do
|
||||
@image.metadata.get('Meta5').value == "MetaValue5"
|
||||
end
|
||||
end
|
||||
|
||||
tests("#destroy('Meta5')").succeeds do
|
||||
@image.metadata.destroy('Meta5')
|
||||
test("metadata has been destroyed") do
|
||||
@image.metadata.get('Meta5') == nil
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
unless Fog.mocking?
|
||||
@image.destroy
|
||||
end
|
||||
@server.destroy
|
||||
|
||||
end
|
|
@ -0,0 +1,54 @@
|
|||
Shindo.tests("Fog::Compute[:hp] | metadata for servers", ['hp']) do
|
||||
|
||||
@base_image_id = ENV["BASE_IMAGE_ID"] || 1242
|
||||
|
||||
@server = Fog::Compute[:hp].servers.create(:name => "fogsermetadatatests", :flavor_id => 100, :image_id => @base_image_id, :metadata => {'Meta1' => 'MetaValue1', 'Meta2' => 'MetaValue2'})
|
||||
@server.wait_for { ready? }
|
||||
|
||||
tests('success') do
|
||||
|
||||
tests("#all").succeeds do
|
||||
@server.metadata.all
|
||||
end
|
||||
|
||||
tests("#get('Meta1')").succeeds do
|
||||
@data = @server.metadata.get('Meta1')
|
||||
test("metadata gets correct value") do
|
||||
@data.value == "MetaValue1"
|
||||
end
|
||||
end
|
||||
|
||||
tests("#update({'Meta3' => 'MetaValue3'})").succeeds do
|
||||
@data = @server.metadata.update({'Meta3' => 'MetaValue3'})
|
||||
test("metadata has updated correctly") do
|
||||
@server.metadata.get('Meta3').value == "MetaValue3"
|
||||
end
|
||||
end
|
||||
|
||||
tests("#set({'Meta4' => 'MetaValue4'})").succeeds do
|
||||
@data = @server.metadata.set({'Meta4' => 'MetaValue4'})
|
||||
test("metadata has set correctly") do
|
||||
@server.metadata.get('Meta4').value == "MetaValue4"
|
||||
end
|
||||
end
|
||||
|
||||
tests("#save").succeeds do
|
||||
m = @server.metadata.new(:key => 'Meta5', :value => 'MetaValue5')
|
||||
@data = m.save
|
||||
test("metadata has saved correctly") do
|
||||
@server.metadata.get('Meta5').value == "MetaValue5"
|
||||
end
|
||||
end
|
||||
|
||||
tests("#destroy('Meta5')").succeeds do
|
||||
@data = @server.metadata.destroy('Meta5')
|
||||
test("metadata has been destroyed") do
|
||||
@server.metadata.get('Meta5') == nil
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@server.destroy
|
||||
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
Shindo.tests("Fog::Compute[:hp] | security_group", ["hp"]) do
|
||||
Shindo.tests("Fog::Compute[:hp] | security_group", ['hp']) do
|
||||
|
||||
model_tests(Fog::Compute[:hp].security_groups, {:name => 'foggroupname', :description => 'foggroupdescription'}, true)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Shindo.tests("Fog::Compute[:hp] | security_groups", ["hp"]) do
|
||||
Shindo.tests("Fog::Compute[:hp] | security_groups", ['hp']) do
|
||||
|
||||
collection_tests(Fog::Compute[:hp].security_groups, {:name => 'foggroupname', :description => 'foggroupdescription'}, true)
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
Shindo.tests("Fog::Storage[:hp] | directories", ['hp', 'storage']) do
|
||||
|
||||
collection_tests(Fog::Storage[:hp].directories, {:key => "fogdirtests"}, true)
|
||||
|
||||
tests('success') do
|
||||
|
||||
tests("#create('fogdirtests')").succeeds do
|
||||
Fog::Storage[:hp].directories.create(:key => 'fogdirtests')
|
||||
end
|
||||
|
||||
tests("#head('fogdirtests')").succeeds do
|
||||
Fog::Storage[:hp].directories.head('fogdirtests')
|
||||
end
|
||||
|
||||
tests("#get('fogdirtests')").succeeds do
|
||||
@directory = Fog::Storage[:hp].directories.get('fogdirtests')
|
||||
end
|
||||
|
||||
@directory.destroy
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,62 @@
|
|||
Shindo.tests("Fog::Storage[:hp] | directory", ['hp', 'storage']) do
|
||||
|
||||
model_tests(Fog::Storage[:hp].directories, {:key => "fogdirtests"}, true) do
|
||||
|
||||
tests('success') do
|
||||
|
||||
tests("#grant('pr')").succeeds do
|
||||
@instance.grant('pr')
|
||||
tests("public?").returns(true) do
|
||||
@instance.public?
|
||||
end
|
||||
end
|
||||
|
||||
tests("#revoke('pr')").succeeds do
|
||||
@instance.revoke('pr')
|
||||
tests("public?").returns(false) do
|
||||
@instance.public?
|
||||
end
|
||||
end
|
||||
|
||||
@instance.files.create(:key => 'sample.txt', :body => lorem_file)
|
||||
tests("#files").succeeds do
|
||||
@instance.files
|
||||
end
|
||||
@instance.files.get('sample.txt').destroy
|
||||
|
||||
tests("#cdn_enable=(true)").succeeds do
|
||||
pending if Fog.mocking?
|
||||
@instance.cdn_enable=(true)
|
||||
tests("cdn_enabled?").returns(true) do
|
||||
pending if Fog.mocking?
|
||||
@instance.cdn_enable?
|
||||
end
|
||||
end
|
||||
|
||||
tests("#cdn_public_url").succeeds do
|
||||
pending if Fog.mocking?
|
||||
@instance.cdn_public_url
|
||||
end
|
||||
|
||||
tests("#cdn_public_ssl_url").succeeds do
|
||||
pending if Fog.mocking?
|
||||
@instance.cdn_public_ssl_url
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
tests('failure') do
|
||||
|
||||
tests("#grant('invalid-acl')").raises(ArgumentError) do
|
||||
@instance.grant('invalid-acl')
|
||||
end
|
||||
|
||||
tests("#revoke('invalid-acl')").raises(ArgumentError) do
|
||||
@instance.revoke('invalid-acl')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,44 @@
|
|||
Shindo.tests("Fog::Storage[:hp] | directory", ['hp', 'storage']) do
|
||||
|
||||
file_attributes = {
|
||||
:key => 'fog_file_tests',
|
||||
:body => lorem_file,
|
||||
:public => true
|
||||
}
|
||||
|
||||
directory_attributes = {
|
||||
:key => 'fogfilestests'
|
||||
}
|
||||
|
||||
@directory = Fog::Storage[:hp].directories.create(directory_attributes)
|
||||
|
||||
model_tests(@directory.files, file_attributes, true) do
|
||||
|
||||
@file = @directory.files.get('fog_file_tests')
|
||||
|
||||
tests('success') do
|
||||
|
||||
tests("#directory").returns(@directory.key) do
|
||||
@file.directory.key
|
||||
end
|
||||
|
||||
tests("#cdn_public_url").succeeds do
|
||||
pending if Fog.mocking?
|
||||
@file.cdn_public_url
|
||||
end
|
||||
|
||||
tests("#cdn_public_ssl_url").succeeds do
|
||||
pending if Fog.mocking?
|
||||
@file.cdn_public_ssl_url
|
||||
end
|
||||
|
||||
tests("#temp_signed_url(60, 'GET')").succeeds do
|
||||
@file.temp_signed_url(60, 'GET')
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@directory.destroy
|
||||
|
||||
end
|
|
@ -0,0 +1,38 @@
|
|||
Shindo.tests("Fog::Storage[:hp] | files", ['hp', 'storage']) do
|
||||
|
||||
file_attributes = {
|
||||
:key => 'fog_files_tests',
|
||||
:body => lorem_file
|
||||
}
|
||||
|
||||
directory_attributes = {
|
||||
:key => 'fogfilestests'
|
||||
}
|
||||
|
||||
collection_tests(Fog::Storage[:hp].directories.create(directory_attributes).files, file_attributes, true)
|
||||
|
||||
@directory = Fog::Storage[:hp].directories.create(directory_attributes)
|
||||
@file = @directory.files.create(file_attributes)
|
||||
|
||||
tests('success') do
|
||||
|
||||
tests("#get_url('#{@directory.key}')").succeeds do
|
||||
@directory.files.get_url(@directory.key)
|
||||
end
|
||||
|
||||
tests("#get_cdn_url('#{@directory.key}')").succeeds do
|
||||
pending if Fog.mocking?
|
||||
@directory.files.get_cdn_url(@directory.key)
|
||||
end
|
||||
|
||||
tests("#get_cdn_ssl_url('#{@directory.key}')").succeeds do
|
||||
pending if Fog.mocking?
|
||||
@directory.files.get_cdn_ssl_url(@directory.key)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@file.destroy
|
||||
@directory.destroy
|
||||
|
||||
end
|
|
@ -0,0 +1,78 @@
|
|||
Shindo.tests("HP::BlockStorage | bootable volume requests", ['hp', 'block_storage', 'volumes']) do
|
||||
|
||||
@volume_format = {
|
||||
'status' => String,
|
||||
'displayDescription' => Fog::Nullable::String,
|
||||
'availabilityZone' => String,
|
||||
'displayName' => Fog::Nullable::String,
|
||||
'attachments' => [Fog::Nullable::Hash],
|
||||
'volumeType' => Fog::Nullable::String,
|
||||
'snapshotId' => Fog::Nullable::String,
|
||||
'size' => Integer,
|
||||
'id' => Integer,
|
||||
'createdAt' => String,
|
||||
'metadata' => Fog::Nullable::Hash
|
||||
}
|
||||
|
||||
@boot_volume_format = {
|
||||
'status' => String,
|
||||
'displayDescription' => Fog::Nullable::String,
|
||||
'availabilityZone' => String,
|
||||
'displayName' => Fog::Nullable::String,
|
||||
'attachments' => [Fog::Nullable::Hash],
|
||||
'volumeType' => Fog::Nullable::String,
|
||||
'snapshotId' => Fog::Nullable::String,
|
||||
'source_image_id' => Fog::Nullable::String,
|
||||
'size' => Integer,
|
||||
'id' => Integer,
|
||||
'createdAt' => String,
|
||||
'metadata' => Fog::Nullable::Hash
|
||||
}
|
||||
|
||||
@volume_attach_format = {
|
||||
"volumeId" => Integer,
|
||||
"id" => Integer
|
||||
}
|
||||
|
||||
tests('success') do
|
||||
|
||||
@volume_id = nil
|
||||
@volume_name = "fogbvolumetests"
|
||||
@volume_desc = @volume_name + " desc"
|
||||
@base_image_id = ENV["BASE_IMAGE_ID"] || 1242
|
||||
|
||||
tests("#create_volume(#{@volume_name}, #{@volume_desc}, 10, {'imageRef' => '#{@base_image_id}'})").formats(@volume_format) do
|
||||
data = HP[:block_storage].create_volume(@volume_name, @volume_desc, 10, {'imageRef' => "#{@base_image_id}"}).body['volume']
|
||||
@volume_id = data['id']
|
||||
data
|
||||
end
|
||||
|
||||
HP[:block_storage].volumes.get(@volume_id).wait_for { ready? }
|
||||
tests("#get_bootable_volume_details(#{@volume_id})").formats(@boot_volume_format) do
|
||||
HP[:block_storage].get_bootable_volume_details(@volume_id).body['volume']
|
||||
end
|
||||
|
||||
tests("#list_bootable_volumes").formats({'volumes' => [@boot_volume_format]}) do
|
||||
HP[:block_storage].list_bootable_volumes.body
|
||||
end
|
||||
|
||||
HP[:block_storage].volumes.get(@volume_id).wait_for { ready? }
|
||||
tests("#delete_volume(#{@volume_id})").succeeds do
|
||||
HP[:block_storage].delete_volume(@volume_id)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
tests('failure') do
|
||||
|
||||
tests("#get_bootable_volume_details(0)").raises(Fog::HP::BlockStorage::NotFound) do
|
||||
HP[:block_storage].get_bootable_volume_details(0)
|
||||
end
|
||||
|
||||
tests("#delete_volume(0)").raises(Fog::HP::BlockStorage::NotFound) do
|
||||
HP[:block_storage].delete_volume(0)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,56 @@
|
|||
Shindo.tests('HP::BlockStorage | snapshot requests', ['hp', 'block_storage', 'snapshots']) do
|
||||
|
||||
@snapshot_format = {
|
||||
'status' => String,
|
||||
'displayDescription' => Fog::Nullable::String,
|
||||
'displayName' => Fog::Nullable::String,
|
||||
'volumeId' => Integer,
|
||||
'size' => Integer,
|
||||
'id' => Integer,
|
||||
'createdAt' => String
|
||||
}
|
||||
|
||||
tests('success') do
|
||||
|
||||
@snapshot_id = nil
|
||||
@snapshot_name = "fogsnapshottests"
|
||||
@snapshot_desc = @snapshot_name + " desc"
|
||||
|
||||
@volume = HP[:block_storage].volumes.create(:name => 'fogvolforsnap', :size => 1)
|
||||
@volume.wait_for { ready? }
|
||||
|
||||
tests("#create_snapshot(#{@snapshot_name}, #{@snapshot_desc}, #{@volume.id})").formats(@snapshot_format) do
|
||||
data = HP[:block_storage].create_snapshot(@snapshot_name, @snapshot_desc, @volume.id).body['snapshot']
|
||||
@snapshot_id = data['id']
|
||||
data
|
||||
end
|
||||
|
||||
tests("#get_snapshot_details(#{@snapshot_id})").formats(@snapshot_format) do
|
||||
HP[:block_storage].get_snapshot_details(@snapshot_id).body['snapshot']
|
||||
end
|
||||
|
||||
tests('#list_snapshots').formats({'snapshots' => [@snapshot_format]}) do
|
||||
HP[:block_storage].list_snapshots.body
|
||||
end
|
||||
|
||||
tests("#delete_snapshot(#{@snapshot_id})").succeeds do
|
||||
HP[:block_storage].delete_snapshot(@snapshot_id)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
tests('failure') do
|
||||
|
||||
tests('#get_snapshot_details(0)').raises(Fog::HP::BlockStorage::NotFound) do
|
||||
HP[:block_storage].get_snapshot_details(0)
|
||||
end
|
||||
|
||||
tests("#delete_snapshot(0)").raises(Fog::HP::BlockStorage::NotFound) do
|
||||
HP[:block_storage].delete_snapshot(0)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@volume.destroy
|
||||
|
||||
end
|
|
@ -0,0 +1,94 @@
|
|||
Shindo.tests("HP::BlockStorage | volume requests", ['hp', 'block_storage', 'volumes']) do
|
||||
|
||||
@volume_format = {
|
||||
'status' => String,
|
||||
'displayDescription' => Fog::Nullable::String,
|
||||
'availabilityZone' => String,
|
||||
'displayName' => Fog::Nullable::String,
|
||||
'attachments' => [Fog::Nullable::Hash],
|
||||
'volumeType' => Fog::Nullable::String,
|
||||
'snapshotId' => Fog::Nullable::String,
|
||||
'size' => Integer,
|
||||
'id' => Integer,
|
||||
'createdAt' => String,
|
||||
'metadata' => Fog::Nullable::Hash
|
||||
}
|
||||
|
||||
@volume_attach_format = {
|
||||
"volumeId" => Integer,
|
||||
"id" => Integer
|
||||
}
|
||||
|
||||
tests('success') do
|
||||
|
||||
@volume_id = nil
|
||||
@volume_name = "fogvolumetests"
|
||||
@volume_desc = @volume_name + " desc"
|
||||
@base_image_id = ENV["BASE_IMAGE_ID"] || 1242
|
||||
|
||||
@server = Fog::Compute[:hp].servers.create(:name => 'fogvoltests', :flavor_id => 100, :image_id => @base_image_id)
|
||||
@server.wait_for { ready? }
|
||||
|
||||
tests("#create_volume(#{@volume_name}, #{@volume_desc}, 1)").formats(@volume_format) do
|
||||
data = HP[:block_storage].create_volume(@volume_name, @volume_desc, 1).body['volume']
|
||||
@volume_id = data['id']
|
||||
data
|
||||
end
|
||||
|
||||
HP[:block_storage].volumes.get(@volume_id).wait_for { ready? }
|
||||
tests("#get_volume_details(#{@volume_id})").formats(@volume_format) do
|
||||
HP[:block_storage].get_volume_details(@volume_id).body['volume']
|
||||
end
|
||||
|
||||
tests('#list_volumes').formats({'volumes' => [@volume_format]}) do
|
||||
HP[:block_storage].list_volumes.body
|
||||
end
|
||||
|
||||
HP[:block_storage].volumes.get(@volume_id).wait_for { ready? }
|
||||
tests("#attach_volume(#{@server.id}, #{@volume_id}, '/dev/sdg')").formats(@volume_attach_format) do
|
||||
Fog::Compute[:hp].attach_volume(@server.id, @volume_id, "/dev/sdg").body['volumeAttachment']
|
||||
end
|
||||
|
||||
HP[:block_storage].volumes.get(@volume_id).wait_for { in_use? } unless Fog.mocking?
|
||||
tests("#detach_volume(#{@server.id}, #{@volume_id})").succeeds do
|
||||
Fog::Compute[:hp].detach_volume(@server.id, @volume_id)
|
||||
end
|
||||
|
||||
HP[:block_storage].volumes.get(@volume_id).wait_for { ready? }
|
||||
tests("#delete_volume(#{@volume_id})").succeeds do
|
||||
HP[:block_storage].delete_volume(@volume_id)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
tests('failure') do
|
||||
|
||||
tests('#get_volume_details(0)').raises(Fog::HP::BlockStorage::NotFound) do
|
||||
HP[:block_storage].get_volume_details(0)
|
||||
end
|
||||
|
||||
tests("#attach_volume(0, 0, '/dev/sdg')").raises(Fog::Compute::HP::NotFound) do
|
||||
Fog::Compute[:hp].attach_volume(0, 0, "/dev/sdg")
|
||||
end
|
||||
tests("#attach_volume(#{@server.id}, 0, '/dev/sdg')").raises(Fog::HP::BlockStorage::NotFound) do
|
||||
pending if Fog.mocking?
|
||||
Fog::Compute[:hp].attach_volume(@server.id, 0, "/dev/sdg")
|
||||
end
|
||||
|
||||
tests("#detach_volume(0, 0)").raises(Fog::Compute::HP::NotFound) do
|
||||
Fog::Compute[:hp].detach_volume(0, 0)
|
||||
end
|
||||
tests("#detach_volume(#{@server.id}, 0)").raises(Fog::HP::BlockStorage::NotFound) do
|
||||
pending if Fog.mocking?
|
||||
Fog::Compute[:hp].detach_volume(@server.id, 0)
|
||||
end
|
||||
|
||||
tests("#delete_volume(0)").raises(Fog::HP::BlockStorage::NotFound) do
|
||||
HP[:block_storage].delete_volume(0)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@server.destroy
|
||||
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
Shindo.tests('Fog::CDN[:hp] | container requests', ["hp"]) do
|
||||
Shindo.tests("Fog::CDN[:hp] | container requests", ['hp']) do
|
||||
|
||||
@cdn_containers_format = [{
|
||||
'x-cdn-ssl-uri' => String,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Shindo.tests('Fog::Compute[:hp] | address requests', ["hp"]) do
|
||||
Shindo.tests("Fog::Compute[:hp] | address requests", ['hp', 'address']) do
|
||||
|
||||
@floating_ips_format = {
|
||||
'instance_id' => Fog::Nullable::Integer,
|
||||
|
@ -30,12 +30,11 @@ Shindo.tests('Fog::Compute[:hp] | address requests', ["hp"]) do
|
|||
@server.wait_for { ready? }
|
||||
|
||||
tests("#associate_address('#{@server.id}', '#{@ip_address}')").succeeds do
|
||||
result = Fog::Compute[:hp].associate_address(@server.id, @ip_address)
|
||||
tests("#get_address").returns(@server.id, "associated to valid instance id") do
|
||||
pending if Fog.mocking?
|
||||
Fog::Compute[:hp].get_address(@address_id).body['floating_ip']['instance_id']
|
||||
Fog::Compute[:hp].associate_address(@server.id, @ip_address)
|
||||
tests("#get_address").returns(@ip_address, "server has associated ip address") do
|
||||
@server.reload
|
||||
@server.addresses['private'][1]['addr']
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
tests("#disassociate_address('#{@server.id}', '#{@ip_address}')").succeeds do
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Shindo.tests('Fog::Compute[:hp] | flavor requests', ["hp"]) do
|
||||
Shindo.tests("Fog::Compute[:hp] | flavor requests", ['hp']) do
|
||||
|
||||
@flavor_format = {
|
||||
'rxtx_quota' => Integer,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Shindo.tests('Fog::Compute[:hp] | image requests', ["hp"]) do
|
||||
Shindo.tests("Fog::Compute[:hp] | image requests", ['hp']) do
|
||||
|
||||
@image_format = {
|
||||
'id' => String,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Shindo.tests('Fog::Compute[:hp] | key pair requests', ["hp"]) do
|
||||
Shindo.tests("Fog::Compute[:hp] | key pair requests", ['hp']) do
|
||||
|
||||
tests('success') do
|
||||
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
Shindo.tests("Fog::Compute[:hp] | metadata requests", ['hp']) do
|
||||
|
||||
@metadata_format = {
|
||||
'metadata' => Fog::Nullable::Hash
|
||||
}
|
||||
@metaitem_format = {
|
||||
'meta' => Fog::Nullable::Hash
|
||||
}
|
||||
|
||||
@base_image_id = ENV["BASE_IMAGE_ID"] || 1242
|
||||
|
||||
tests('success') do
|
||||
@server_name = "fogmetadatatest"
|
||||
@server = Fog::Compute[:hp].servers.create(:name => @server_name, :flavor_id => 100, :image_id => @base_image_id, :metadata => {'Meta1' => 'MetaValue1', 'Meta2' => 'MetaValue2'} )
|
||||
@server.wait_for { ready? }
|
||||
|
||||
tests("#list_metadata('servers', #{@server.id})").formats(@metadata_format) do
|
||||
metadata = Fog::Compute[:hp].list_metadata('servers', @server.id).body
|
||||
test ("metadata exists") do
|
||||
metadata['metadata']['Meta1'] == "MetaValue1"
|
||||
end
|
||||
metadata
|
||||
end
|
||||
|
||||
tests("#set_metadata('servers', #{@server.id}, {'MetaNew3' => 'MetaNewValue3'})").formats(@metadata_format) do
|
||||
data = Fog::Compute[:hp].set_metadata('servers', @server.id, {'MetaNew3' => 'MetaNewValue3'}).body
|
||||
test ("metadata set correctly") do
|
||||
metadata = Fog::Compute[:hp].list_metadata('servers', @server.id).body
|
||||
metadata['metadata']['MetaNew3'] == "MetaNewValue3"
|
||||
end
|
||||
data
|
||||
end
|
||||
|
||||
tests("#update_metadata('servers', #{@server.id}, {'MetaUpd4' => 'MetaUpdValue4'})").formats(@metadata_format) do
|
||||
data = Fog::Compute[:hp].update_metadata('servers', @server.id, {'MetaUpd4' => 'MetaUpdValue4'}).body
|
||||
test ("metadata updated correctly") do
|
||||
metadata = Fog::Compute[:hp].list_metadata('servers', @server.id).body
|
||||
metadata['metadata']['MetaUpd4'] == "MetaUpdValue4"
|
||||
end
|
||||
data
|
||||
end
|
||||
|
||||
tests("#get_meta('servers', #{@server.id}, 'MetaNew3')").formats(@metaitem_format) do
|
||||
mitem = Fog::Compute[:hp].get_meta('servers', @server.id, 'MetaNew3').body
|
||||
test ("metadata item exists") do
|
||||
mitem['meta']['MetaNew3'] == "MetaNewValue3"
|
||||
end
|
||||
mitem
|
||||
end
|
||||
|
||||
tests("#update_meta('servers', #{@server.id}, 'MetaNew3', 'MetaUpdValue3')").formats(@metaitem_format) do
|
||||
mitem = Fog::Compute[:hp].update_meta('servers', @server.id, 'MetaNew3', 'MetaUpdValue3').body
|
||||
test ("metadata item updated correctly") do
|
||||
mitem['meta']['MetaNew3'] == "MetaUpdValue3"
|
||||
end
|
||||
mitem
|
||||
end
|
||||
|
||||
tests("#delete_meta('servers', #{@server.id}, 'MetaNew3')").succeeds do
|
||||
data = Fog::Compute[:hp].delete_meta('servers', @server.id, 'MetaNew3').body
|
||||
test ("metadata item deleted correctly") do
|
||||
metadata = Fog::Compute[:hp].list_metadata('servers', @server.id).body
|
||||
metadata['metadata'].fetch('MetaNew3', nil) == nil
|
||||
end
|
||||
data
|
||||
end
|
||||
|
||||
@server.destroy
|
||||
end
|
||||
end
|
|
@ -0,0 +1,66 @@
|
|||
Shindo.tests("Fog::Compute[:hp] | persistent server requests", ['hp', 'compute']) do
|
||||
|
||||
@server_format = {
|
||||
'addresses' => Fog::Nullable::Hash,
|
||||
'flavor' => Hash,
|
||||
'id' => Integer,
|
||||
'links' => [Hash],
|
||||
'hostId' => String,
|
||||
'metadata' => Fog::Nullable::Hash,
|
||||
'name' => String,
|
||||
'accessIPv4' => Fog::Nullable::String,
|
||||
'accessIPv6' => Fog::Nullable::String,
|
||||
'progress' => Fog::Nullable::Integer,
|
||||
'status' => String,
|
||||
'created' => String,
|
||||
'updated' => String,
|
||||
'user_id' => String,
|
||||
'tenant_id' => String,
|
||||
'uuid' => String,
|
||||
'config_drive' => Fog::Nullable::String,
|
||||
'security_groups' => [Hash],
|
||||
'key_name' => Fog::Nullable::String
|
||||
}
|
||||
|
||||
@volume = HP[:block_storage].volumes.create(:name => 'fogvoltests', :description => 'fog vol test desc', :size => 1)
|
||||
@volume.wait_for { ready? }
|
||||
|
||||
tests('success') do
|
||||
|
||||
@server_id = nil
|
||||
@server_name = "fogpersservertests"
|
||||
@block_device_mapping = [{ 'volume_size' => '',
|
||||
'volume_id' => "#{@volume.id}",
|
||||
'delete_on_termination' => '0',
|
||||
'device_name' => 'vda'
|
||||
}]
|
||||
|
||||
tests("#create_persistent_server(#{@server_name}, 100, #{@block_device_mapping})").formats(@server_format.merge('adminPass' => String)) do
|
||||
data = Fog::Compute[:hp].create_persistent_server(@server_name, 100, @block_device_mapping).body['server']
|
||||
@server_id = data['id']
|
||||
data
|
||||
end
|
||||
|
||||
Fog::Compute[:hp].servers.get(@server_id).wait_for { ready? }
|
||||
|
||||
tests("#get_server_details(#{@server_id})").formats(@server_format) do
|
||||
Fog::Compute[:hp].get_server_details(@server_id).body['server']
|
||||
end
|
||||
|
||||
tests("#delete_server(#{@server_id})").succeeds do
|
||||
Fog::Compute[:hp].delete_server(@server_id)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
tests('failure') do
|
||||
|
||||
tests("#create_persistent_server(#{@server_name}, 100, nil)").raises(Excon::Errors::BadRequest) do
|
||||
Fog::Compute[:hp].create_persistent_server(@server_name, 100, nil)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
HP[:block_storage].delete_volume(@volume.id)
|
||||
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
Shindo.tests('Fog::Compute[:hp] | security group requests', ["hp"]) do
|
||||
Shindo.tests("Fog::Compute[:hp] | security group requests", ['hp']) do
|
||||
|
||||
@security_group_rule_format = {
|
||||
'from_port' => Integer,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Shindo.tests('Fog::Compute[:hp] | security group requests', ["hp"]) do
|
||||
Shindo.tests("Fog::Compute[:hp] | security group requests", ['hp']) do
|
||||
|
||||
@security_groups_format = {
|
||||
'security_groups' => [{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Shindo.tests('Fog::Compute[:hp] | address requests', ["hp"]) do
|
||||
Shindo.tests("Fog::Compute[:hp] | address requests", ['hp']) do
|
||||
|
||||
@base_image_id = ENV["BASE_IMAGE_ID"] || 1242
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче