Revert "Moving Rackspace logic to fog-rackspace"

This reverts commit d6ecb19d24.

Conflicts:
	fog.gemspec
This commit is contained in:
Matt Darby 2014-12-10 11:30:34 -05:00
Родитель 909cb31571
Коммит 72e52e70be
609 изменённых файлов: 36246 добавлений и 1 удалений

Просмотреть файл

@ -84,7 +84,7 @@ Collections share basic CRUD type operations, such as:
As an example, we'll try initializing and persisting a Rackspace Cloud server:
```ruby
require 'fog/rackspace'
require 'fog'
compute = Fog::Compute.new(
:provider => 'Rackspace',

Просмотреть файл

@ -44,6 +44,7 @@ require 'fog/linode'
require 'fog/local'
require 'fog/bare_metal_cloud'
require 'fog/ninefold'
require 'fog/rackspace'
require 'fog/rage4'
require 'fog/riakcs'
require 'fog/openstack'

Просмотреть файл

@ -76,6 +76,7 @@ require 'fog/bin/linode'
require 'fog/bin/local'
require 'fog/bin/bare_metal_cloud'
require 'fog/bin/ninefold'
require 'fog/bin/rackspace'
require 'fog/bin/rage4'
require 'fog/bin/riakcs'
require 'fog/bin/openstack'

81
lib/fog/bin/rackspace.rb Normal file
Просмотреть файл

@ -0,0 +1,81 @@
class Rackspace < Fog::Bin
class << self
def class_for(key)
case key
when :auto_scale
Fog::Rackspace::AutoScale
when :block_storage
Fog::Rackspace::BlockStorage
when :cdn
Fog::CDN::Rackspace
when :compute
Fog::Compute::Rackspace
when :compute_v2
Fog::Compute::RackspaceV2
when :storage
Fog::Storage::Rackspace
when :load_balancers
Fog::Rackspace::LoadBalancers
when :dns
Fog::DNS::Rackspace
when :identity
Fog::Rackspace::Identity
when :databases
Fog::Rackspace::Databases
when :monitoring
Fog::Rackspace::Monitoring
when :queues
Fog::Rackspace::Queues
when :networking
Fog::Rackspace::Networking
else
raise ArgumentError, "Unrecognized service: #{key}"
end
end
def [](service)
@@connections ||= Hash.new do |hash, key|
hash[key] = case key
when :auto_scale
Fog::Rackspace::AutoScale.new
when :cdn
Fog::Logger.warning("Rackspace[:cdn] is not recommended, use CDN[:rackspace] for portability")
Fog::CDN.new(:provider => 'Rackspace')
when :compute
Fog::Logger.warning("Rackspace[:compute] is not recommended, use Compute[:rackspace] for portability")
Fog::Compute.new(:provider => 'Rackspace')
when :compute_v2
Fog::Logger.warning("Rackspace[:compute] is not recommended, use Compute[:rackspace] for portability")
Fog::Compute.new(:provider => 'Rackspace', :version => 'v2')
when :dns
Fog::DNS.new(:provider => 'Rackspace')
when :load_balancers
Fog::Rackspace::LoadBalancers.new
when :storage
Fog::Logger.warning("Rackspace[:storage] is not recommended, use Storage[:rackspace] for portability")
Fog::Storage.new(:provider => 'Rackspace')
when :identity
Fog::Logger.warning("Rackspace[:identity] is not recommended, use Identity[:rackspace] for portability")
Fog::Identity.new(:provider => 'Rackspace')
when :databases
Fog::Rackspace::Databases.new
when :block_storage
Fog::Rackspace::BlockStorage.new
when :monitoring
Fog::Rackspace::Monitoring.new
when :queues
Fog::Rackspace::Queues.new
when :networking
Fog::Rackspace::Networking.new
else
raise ArgumentError, "Unrecognized service: #{key.inspect}"
end
end
@@connections[service]
end
def services
Fog::Rackspace.services
end
end
end

13
lib/fog/rackspace.rb Normal file
Просмотреть файл

@ -0,0 +1,13 @@
require 'fog/rackspace/auto_scale'
require 'fog/rackspace/block_storage'
require 'fog/rackspace/cdn'
require 'fog/rackspace/compute'
require 'fog/rackspace/compute_v2'
require 'fog/rackspace/databases'
require 'fog/rackspace/dns'
require 'fog/rackspace/identity'
require 'fog/rackspace/load_balancers'
require 'fog/rackspace/monitoring'
require 'fog/rackspace/queues'
require 'fog/rackspace/storage'
require 'fog/rackspace/networking'

Просмотреть файл

@ -0,0 +1,134 @@
require 'fog/rackspace/core'
module Fog
module Rackspace
class AutoScale < Fog::Service
include Fog::Rackspace::Errors
class ServiceError < Fog::Rackspace::Errors::ServiceError; end
class InternalServerError < Fog::Rackspace::Errors::InternalServerError; end
class BadRequest < Fog::Rackspace::Errors::BadRequest
attr_reader :validation_errors
def self.slurp(error, service=nil)
if error && error.response
status_code = error.response.status
if error.response.body
body = Fog::JSON.decode(error.response.body)
message = "#{body['type']} - #{body['message']}"
details = error.response.body['details']
end
end
new_error = new(message)
new_error.set_backtrace(error.backtrace)
new_error.instance_variable_set(:@validation_errors, details)
new_error.instance_variable_set(:@status_code, status_code)
new_error.set_transaction_id(error, service)
new_error
end
end
requires :rackspace_username, :rackspace_api_key
recognizes :rackspace_auth_url
recognizes :rackspace_region
recognizes :rackspace_auto_scale_url
model_path 'fog/rackspace/models/auto_scale'
model :group
collection :groups
model :group_config
model :launch_config
model :policy
collection :policies
model :webhook
collection :webhooks
request_path 'fog/rackspace/requests/auto_scale'
request :list_groups
request :create_group
request :get_group
request :delete_group
request :get_group_state
request :pause_group_state
request :resume_group_state
request :get_group_config
request :update_group_config
request :get_launch_config
request :update_launch_config
request :list_policies
request :create_policy
request :get_policy
request :update_policy
request :delete_policy
request :execute_policy
request :execute_anonymous_webhook
request :get_webhook
request :list_webhooks
request :create_webhook
request :update_webhook
request :delete_webhook
class Mock < Fog::Rackspace::Service
def initialize(options)
@rackspace_api_key = options[:rackspace_api_key]
end
def request(params)
Fog::Mock.not_implemented
end
end
class Real < Fog::Rackspace::Service
def initialize(options = {})
@options = options
@options[:connection_options] ||= {}
@options[:persistent] ||= false
authenticate
@connection = Fog::Core::Connection.new(endpoint_uri.to_s, @options[:persistent], @options[:connection_options])
end
def request(params, parse_json = true, &block)
super(params, parse_json, &block)
rescue Excon::Errors::NotFound => error
raise NotFound.slurp(error, self)
rescue Excon::Errors::BadRequest => error
raise BadRequest.slurp(error, self)
rescue Excon::Errors::InternalServerError => error
raise InternalServerError.slurp(error, self)
rescue Excon::Errors::HTTPStatusError => error
raise ServiceError.slurp(error, self)
end
def endpoint_uri(service_endpoint_url=nil)
@uri = super(@options[:rackspace_auto_scale_url], :rackspace_auto_scale_url)
end
def authenticate(options={})
super(select_options([:rackspace_username, :rackspace_api_key, :rackspace_auth_url, :connection_options]))
end
def service_name
:autoscale
end
def request_id_header
"x-response-id"
end
def region
@options[:rackspace_region]
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,175 @@
require 'fog/rackspace/core'
module Fog
module Rackspace
class BlockStorage < Fog::Service
include Fog::Rackspace::Errors
class IdentifierTaken < Fog::Errors::Error; end
class ServiceError < Fog::Rackspace::Errors::ServiceError; end
class InternalServerError < Fog::Rackspace::Errors::InternalServerError; end
class BadRequest < Fog::Rackspace::Errors::BadRequest; end
DFW_ENDPOINT = 'https://dfw.blockstorage.api.rackspacecloud.com/v1'
LON_ENDPOINT = 'https://lon.blockstorage.api.rackspacecloud.com/v1'
ORD_ENDPOINT = 'https://ord.blockstorage.api.rackspacecloud.com/v1'
requires :rackspace_api_key, :rackspace_username
recognizes :rackspace_auth_url
recognizes :rackspace_endpoint
recognizes :rackspace_region
recognizes :rackspace_block_storage_url
model_path 'fog/rackspace/models/block_storage'
model :volume
collection :volumes
model :volume_type
collection :volume_types
model :snapshot
collection :snapshots
request_path 'fog/rackspace/requests/block_storage'
request :create_volume
request :delete_volume
request :get_volume
request :list_volumes
request :get_volume_type
request :list_volume_types
request :create_snapshot
request :delete_snapshot
request :get_snapshot
request :list_snapshots
class Mock < Fog::Rackspace::Service
include Fog::Rackspace::MockData
def initialize(options = {})
@rackspace_api_key = options[:rackspace_api_key]
end
def request(params)
Fog::Mock.not_implemented
end
def response(params={})
body = params[:body] || {}
status = params[:status] || 200
headers = params[:headers] || {}
response = Excon::Response.new(:body => body, :headers => headers, :status => status)
if params.key?(:expects) && ![*params[:expects]].include?(response.status)
raise(Excon::Errors.status_error(params, response))
else response
end
end
end
class Real < Fog::Rackspace::Service
def initialize(options = {})
@rackspace_api_key = options[:rackspace_api_key]
@rackspace_username = options[:rackspace_username]
@rackspace_auth_url = options[:rackspace_auth_url]
@rackspace_must_reauthenticate = false
@connection_options = options[:connection_options] || {}
setup_custom_endpoint(options)
authenticate
deprecation_warnings(options)
@persistent = options[:persistent] || false
@connection = Fog::Core::Connection.new(endpoint_uri.to_s, @persistent, @connection_options)
end
def request(params, parse_json = true)
super
rescue Excon::Errors::NotFound => error
raise NotFound.slurp(error, self)
rescue Excon::Errors::BadRequest => error
raise BadRequest.slurp(error, self)
rescue Excon::Errors::InternalServerError => error
raise InternalServerError.slurp(error, self)
rescue Excon::Errors::HTTPStatusError => error
raise ServiceError.slurp(error, self)
end
def authenticate(options={})
super({
:rackspace_api_key => @rackspace_api_key,
:rackspace_username => @rackspace_username,
:rackspace_auth_url => @rackspace_auth_url,
:connection_options => @connection_options
})
end
def service_name
:cloudBlockStorage
end
def region
@rackspace_region
end
def request_id_header
"X-Compute-Request-Id"
end
def endpoint_uri(service_endpoint_url=nil)
@uri = super(@rackspace_endpoint || service_endpoint_url, :rackspace_block_storage_url)
end
private
def setup_custom_endpoint(options)
@rackspace_endpoint = Fog::Rackspace.normalize_url(options[:rackspace_block_storage_url] || options[:rackspace_endpoint])
if v2_authentication?
case @rackspace_endpoint
when DFW_ENDPOINT
@rackspace_endpoint = nil
@rackspace_region = :dfw
when ORD_ENDPOINT
@rackspace_endpoint = nil
@rackspace_region = :ord
when LON_ENDPOINT
@rackspace_endpoint = nil
@rackspace_region = :lon
else
@rackspace_region = options[:rackspace_region]
end
else
#if we are using auth1 and the endpoint is not set, default to DFW_ENDPOINT for historical reasons
@rackspace_endpoint ||= DFW_ENDPOINT
end
end
def deprecation_warnings(options)
Fog::Logger.deprecation("The :rackspace_endpoint option is deprecated. Please use :rackspace_block_storage_url for custom endpoints") if options[:rackspace_endpoint]
if [DFW_ENDPOINT, ORD_ENDPOINT, LON_ENDPOINT].include?(@rackspace_endpoint) && v2_authentication?
regions = @identity_service.service_catalog.display_service_regions(service_name)
Fog::Logger.deprecation("Please specify region using :rackspace_region rather than :rackspace_endpoint. Valid region for :rackspace_region are #{regions}.")
end
end
def append_tenant_v1(credentials)
account_id = credentials['X-Server-Management-Url'].match(/.*\/([\d]+)$/)[1]
endpoint = @rackspace_endpoint || credentials['X-Server-Management-Url'] || DFW_ENDPOINT
@uri = URI.parse(endpoint)
@uri.path = "#{@uri.path}/#{account_id}"
end
def authenticate_v1(options)
credentials = Fog::Rackspace.authenticate(options, @connection_options)
append_tenant_v1 credentials
@auth_token = credentials['X-Auth-Token']
end
end
end
end
end

198
lib/fog/rackspace/cdn.rb Normal file
Просмотреть файл

@ -0,0 +1,198 @@
require 'fog/rackspace/core'
module Fog
module CDN
class Rackspace < Fog::Service
requires :rackspace_api_key, :rackspace_username
recognizes :rackspace_auth_url, :persistent, :rackspace_cdn_ssl, :rackspace_region, :rackspace_cdn_url
request_path 'fog/rackspace/requests/cdn'
request :get_containers
request :head_container
request :post_container
request :put_container
request :delete_object
module Base
URI_HEADERS = {
"X-Cdn-Ios-Uri" => :ios_uri,
"X-Cdn-Uri" => :uri,
"X-Cdn-Streaming-Uri" => :streaming_uri,
"X-Cdn-Ssl-Uri" => :ssl_uri
}.freeze
def apply_options(options)
# api_key and username missing from instance variable sets
@rackspace_api_key = options[:rackspace_api_key]
@rackspace_username = options[:rackspace_username]
@connection_options = options[:connection_options] || {}
@rackspace_auth_url = options[:rackspace_auth_url]
@rackspace_cdn_url = options[:rackspace_cdn_url]
@rackspace_region = options[:rackspace_region]
end
def service_name
:cloudFilesCDN
end
def region
@rackspace_region
end
def request_id_header
"X-Trans-Id"
end
# Returns true if CDN service is enabled
# @return [Boolean]
def enabled?
@enabled
end
def endpoint_uri(service_endpoint_url=nil)
@uri = super(@rackspace_cdn_url || service_endpoint_url, :rackspace_cdn_url)
end
# Publish container to CDN
# @param [Fog::Storage::Rackspace::Directory] container directory to publish
# @param [Boolean] publish If true directory is published. If false directory is unpublished.
# @return [Hash] hash containing urls for published container
# @raise [Fog::Storage::Rackspace::NotFound] - HTTP 404
# @raise [Fog::Storage::Rackspace::BadRequest] - HTTP 400
# @raise [Fog::Storage::Rackspace::InternalServerError] - HTTP 500
# @raise [Fog::Storage::Rackspace::ServiceError]
def publish_container(container, publish = true)
enabled = publish ? 'True' : 'False'
response = put_container(container.key, 'X-Cdn-Enabled' => enabled)
return {} unless publish
urls_from_headers(response.headers)
end
# Returns hash of urls for container
# @param [Fog::Storage::Rackspace::Directory] container to retrieve urls for
# @return [Hash] hash containing urls for published container
# @raise [Fog::Storage::Rackspace::BadRequest] - HTTP 400
# @raise [Fog::Storage::Rackspace::InternalServerError] - HTTP 500
# @raise [Fog::Storage::Rackspace::ServiceError]
# @note If unable to find container or container is not published this method will return an empty hash.
def urls(container)
begin
response = head_container(container.key)
return {} unless response.headers['X-Cdn-Enabled'] == 'True'
urls_from_headers response.headers
rescue Fog::Service::NotFound
{}
end
end
private
def urls_from_headers(headers)
h = {}
URI_HEADERS.keys.each do | header |
key = URI_HEADERS[header]
h[key] = headers[header]
end
h
end
end
class Mock < Fog::Rackspace::Service
include Base
def self.data
@data ||= Hash.new do |hash, key|
hash[key] = {}
end
end
def self.reset
@data = nil
end
def initialize(options={})
apply_options(options)
authenticate(options)
@enabled = !! endpoint_uri
end
def data
self.class.data[@rackspace_username]
end
def purge(object)
return true if object.is_a? Fog::Storage::Rackspace::File
raise Fog::Errors::NotImplemented.new("#{object.class} does not support CDN purging") if object
end
def reset_data
self.class.data.delete(@rackspace_username)
end
end
class Real < Fog::Rackspace::Service
include Base
def initialize(options={})
apply_options(options)
authenticate(options)
@enabled = false
@persistent = options[:persistent] || false
if endpoint_uri
@connection = Fog::Core::Connection.new(endpoint_uri.to_s, @persistent, @connection_options)
@enabled = true
end
end
# Resets CDN connection
def reload
@cdn_connection.reset
end
# Purges File
# @param [Fog::Storage::Rackspace::File] file to be purged from the CDN
# @raise [Fog::Errors::NotImplemented] returned when non file parameters are specified
def purge(file)
unless file.is_a? Fog::Storage::Rackspace::File
raise Fog::Errors::NotImplemented.new("#{object.class} does not support CDN purging") if object
end
delete_object file.directory.key, file.key
true
end
def request(params, parse_json = true)
super
rescue Excon::Errors::NotFound => error
raise Fog::Storage::Rackspace::NotFound.slurp(error, self)
rescue Excon::Errors::BadRequest => error
raise Fog::Storage::Rackspace::BadRequest.slurp(error, self)
rescue Excon::Errors::InternalServerError => error
raise Fog::Storage::Rackspace::InternalServerError.slurp(error, self)
rescue Excon::Errors::HTTPStatusError => error
raise Fog::Storage::Rackspace::ServiceError.slurp(error, self)
end
private
def authenticate_v1(options)
credentials = Fog::Rackspace.authenticate(options, @connection_options)
endpoint_uri credentials['X-CDN-Management-Url']
@auth_token = credentials['X-Auth-Token']
end
# Fix for invalid auth_token, likely after 24 hours.
def authenticate(options={})
super({
:rackspace_api_key => @rackspace_api_key,
:rackspace_username => @rackspace_username,
:rackspace_auth_url => @rackspace_auth_url,
:connection_options => @connection_options
})
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,256 @@
require 'fog/rackspace/core'
module Fog
module Compute
class Rackspace < Fog::Service
include Fog::Rackspace::Errors
class ServiceError < Fog::Rackspace::Errors::ServiceError; end
class InternalServerError < Fog::Rackspace::Errors::InternalServerError; end
class BadRequest < Fog::Rackspace::Errors::BadRequest; end
requires :rackspace_api_key, :rackspace_username
recognizes :rackspace_auth_url, :rackspace_servicenet, :persistent
recognizes :rackspace_auth_token, :rackspace_management_url, :rackspace_compute_v1_url, :rackspace_region
model_path 'fog/rackspace/models/compute'
model :flavor
collection :flavors
model :image
collection :images
model :server
collection :servers
request_path 'fog/rackspace/requests/compute'
request :confirm_resized_server
request :create_image
request :create_server
request :delete_image
request :delete_server
request :get_flavor_details
request :get_image_details
request :get_server_details
request :list_addresses
request :list_private_addresses
request :list_public_addresses
request :list_flavors
request :list_flavors_detail
request :list_images
request :list_images_detail
request :list_servers
request :list_servers_detail
request :reboot_server
request :revert_resized_server
request :resize_server
request :server_action
request :update_server
class Mock < Fog::Rackspace::Service
def self.data
@data ||= Hash.new do |hash, key|
hash[key] = {
:last_modified => {
:images => {},
:servers => {}
},
:servers => {},
:images => {
112 =>
{'id' => 112,
'status' => "ACTIVE",
'updated' => "2011-04-21T10:24:01-05:00",
'name' => "Ubuntu 10.04 LTS"},
100 =>
{'id' => 100,
'status' => "ACTIVE",
'updated' => "2011-09-12T09:09:23-05:00",
'name' => "Arch 2011.10"},
31 =>
{'id' => 31,
'status' => "ACTIVE",
'updated' => "2010-01-26T12:07:44-06:00",
'name' => "Windows Server 2008 SP2 x86"},
108 =>
{'id' => 108,
'status' => "ACTIVE",
'updated' => "2011-11-01T08:32:30-05:00",
'name' => "Gentoo 11.0"},
109 =>
{'id' => 109,
'status' => "ACTIVE",
'updated' => "2011-11-03T06:28:56-05:00",
'name' => "openSUSE 12"},
89 =>
{'id' => 89,
'status' => "ACTIVE",
'updated' => "2011-10-04T08:39:34-05:00",
'name' => "Windows Server 2008 R2 x64 - SQL2K8R2 Web"},
24 =>
{'id' => 24,
'status' => "ACTIVE",
'updated' => "2010-01-26T12:07:04-06:00",
'name' => "Windows Server 2008 SP2 x64"},
110 =>
{'id' => 110,
'status' => "ACTIVE",
'updated' => "2011-08-17T05:11:30-05:00",
'name' => "Red Hat Enterprise Linux 5.5"},
57 =>
{'id' => 57,
'status' => "ACTIVE",
'updated' => "2010-09-17T07:16:25-05:00",
'name' => "Windows Server 2008 SP2 x64 - MSSQL2K8R2"},
85 =>
{'id' => 85,
'status' => "ACTIVE",
'updated' => "2010-01-26T12:07:17-06:00",
'name' => "Windows Server 2008 R2 x64"},
111 =>
{'id' => 111,
'status' => "ACTIVE",
'updated' => "2011-09-12T10:53:12-05:00",
'name' => "Red Hat Enterprise Linux 6"},
120 =>
{'id' => 120,
'status' => "ACTIVE",
'updated' => "2012-01-03T04:39:05-06:00",
'name' => "Fedora 16"},
119 =>
{'id' => 119,
'status' => "ACTIVE",
'updated' => "2011-11-03T08:55:15-05:00",
'name' => "Ubuntu 11.10"},
116 =>
{'id' => 116,
'status' => "ACTIVE",
'updated' => "2011-08-17T05:11:30-05:00",
'name' => "Fedora 15"},
56 =>
{'id' => 56,
'status' => "ACTIVE",
'updated' => "2010-09-17T07:12:56-05:00",
'name' => "Windows Server 2008 SP2 x86 - MSSQL2K8R2"},
114 =>
{'id' => 114,
'status' => "ACTIVE",
'updated' => "2011-08-17T05:11:30-05:00",
'name' => "CentOS 5.6"},
86 =>
{'id' => 86,
'status' => "ACTIVE",
'updated' => "2010-09-17T07:19:20-05:00",
'name' => "Windows Server 2008 R2 x64 - MSSQL2K8R2"},
115 =>
{'id' => 115,
'status' => "ACTIVE",
'updated' => "2011-08-17T05:11:30-05:00",
'name' => "Ubuntu 11.04"},
103 =>
{'id' => 103,
'status' => "ACTIVE",
'updated' => "2011-08-17T05:11:30-05:00",
'name' => "Debian 5 (Lenny)"},
104 =>
{'id' => 104,
'status' => "ACTIVE",
'updated' => "2011-08-17T05:11:30-05:00",
'name' => "Debian 6 (Squeeze)"},
118 =>
{'id' => 118,
'status' => "ACTIVE",
'updated' => "2011-08-17T05:11:30-05:00",
'name' => "CentOS 6.0"}
}
}
end
end
def self.reset
@data = nil
end
def initialize(options={})
@rackspace_username = options[:rackspace_username]
end
def data
self.class.data[@rackspace_username]
end
def reset_data
self.class.data.delete(@rackspace_username)
end
end
class Real < Fog::Rackspace::Service
def initialize(options={})
@rackspace_api_key = options[:rackspace_api_key]
@rackspace_username = options[:rackspace_username]
@rackspace_auth_url = options[:rackspace_auth_url]
@rackspace_servicenet = options[:rackspace_servicenet]
@rackspace_auth_token = options[:rackspace_auth_token]
@rackspace_endpoint = Fog::Rackspace.normalize_url(options[:rackspace_compute_v1_url] || options[:rackspace_management_url])
@connection_options = options[:connection_options] || {}
authenticate
Excon.defaults[:ssl_verify_peer] = false if service_net?
@persistent = options[:persistent] || false
@connection = Fog::Core::Connection.new(endpoint_uri.to_s, @persistent, @connection_options)
end
def reload
@connection.reset
end
def request(params, parse_json = true)
super
rescue Excon::Errors::NotFound => error
raise NotFound.slurp(error, self)
rescue Excon::Errors::BadRequest => error
raise BadRequest.slurp(error, self)
rescue Excon::Errors::InternalServerError => error
raise InternalServerError.slurp(error, self)
rescue Excon::Errors::HTTPStatusError => error
raise ServiceError.slurp(error, self)
end
def service_net?
@rackspace_servicenet == true
end
def authenticate(options={})
super({
:rackspace_api_key => @rackspace_api_key,
:rackspace_username => @rackspace_username,
:rackspace_auth_url => @rackspace_auth_url,
:connection_options => @connection_options
})
end
def service_name
:cloudServers
end
def region
@rackspace_region
end
def endpoint_uri(service_endpoint_url=nil)
return @uri if @uri
super(@rackspace_endpoint || service_endpoint_url, :rackspace_compute_v1_url)
end
private
def deprecation_warnings(options)
Fog::Logger.deprecation("The :rackspace_management_url option is deprecated. Please use :rackspace_compute_v1_url for custom endpoints") if options[:rackspace_management_url]
end
def authenticate_v1(options)
credentials = Fog::Rackspace.authenticate(options, @connection_options)
endpoint_uri credentials['X-Server-Management-Url']
@auth_token = credentials['X-Auth-Token']
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,250 @@
require 'fog/rackspace/core'
module Fog
module Compute
class RackspaceV2 < Fog::Service
include Fog::Rackspace::Errors
class ServiceError < Fog::Rackspace::Errors::ServiceError; end
class InternalServerError < Fog::Rackspace::Errors::InternalServerError; end
class BadRequest < Fog::Rackspace::Errors::BadRequest; end
class InvalidStateException < ::RuntimeError
attr_reader :desired_state
attr_reader :current_state
def initialize(desired_state, current_state)
@desired_state = desired_state
@current_state = current_state
end
end
class InvalidServerStateException < InvalidStateException
def to_s
"Server should have transitioned to '#{desired_state}' not '#{current_state}'"
end
end
class InvalidImageStateException < InvalidStateException
def to_s
"Image should have transitioned to '#{desired_state}' not '#{current_state}'"
end
end
DFW_ENDPOINT = 'https://dfw.servers.api.rackspacecloud.com/v2'
ORD_ENDPOINT = 'https://ord.servers.api.rackspacecloud.com/v2'
LON_ENDPOINT = 'https://lon.servers.api.rackspacecloud.com/v2'
requires :rackspace_username, :rackspace_api_key
recognizes :rackspace_endpoint
recognizes :rackspace_auth_url
recognizes :rackspace_auth_token
recognizes :rackspace_region
recognizes :rackspace_compute_url
model_path 'fog/rackspace/models/compute_v2'
model :server
collection :servers
model :flavor
collection :flavors
model :image
collection :images
model :attachment
collection :attachments
model :network
collection :networks
model :key_pair
collection :key_pairs
model :virtual_interface
collection :virtual_interfaces
request_path 'fog/rackspace/requests/compute_v2'
request :list_servers
request :get_server
request :create_server
request :update_server
request :delete_server
request :change_server_password
request :reboot_server
request :rebuild_server
request :resize_server
request :confirm_resize_server
request :revert_resize_server
request :rescue_server
request :unrescue_server
request :list_addresses
request :list_addresses_by_network
request :create_image
request :list_images
request :list_images_detail
request :get_image
request :delete_image
request :list_flavors
request :list_flavors_detail
request :get_flavor
request :attach_volume
request :get_attachment
request :list_attachments
request :delete_attachment
request :list_metadata
request :set_metadata
request :update_metadata
request :get_metadata_item
request :set_metadata_item
request :delete_metadata_item
request :list_networks
request :get_network
request :create_network
request :delete_network
request :list_keypairs
request :create_keypair
request :delete_keypair
request :get_keypair
request :list_virtual_interfaces
request :create_virtual_interface
request :delete_virtual_interface
class Mock < Fog::Rackspace::Service
include Fog::Rackspace::MockData
def initialize(options)
@rackspace_api_key = options[:rackspace_api_key]
end
def request(params)
Fog::Mock.not_implemented
end
def response(params={})
body = params[:body] || {}
status = params[:status] || 200
headers = params[:headers] || {}
response = Excon::Response.new(:body => body, :headers => headers, :status => status)
if params.key?(:expects) && ![*params[:expects]].include?(response.status)
raise(Excon::Errors.status_error(params, response))
else response
end
end
end
class Real < Fog::Rackspace::Service
def initialize(options = {})
@rackspace_api_key = options[:rackspace_api_key]
@rackspace_username = options[:rackspace_username]
@rackspace_auth_url = options[:rackspace_auth_url]
setup_custom_endpoint(options)
@rackspace_must_reauthenticate = false
@connection_options = options[:connection_options] || {}
authenticate
deprecation_warnings(options)
@persistent = options[:persistent] || false
@connection = Fog::Core::Connection.new(endpoint_uri.to_s, @persistent, @connection_options)
end
def request(params, parse_json = true)
super
rescue Excon::Errors::NotFound => error
raise NotFound.slurp(error, self)
rescue Excon::Errors::BadRequest => error
raise BadRequest.slurp(error, self)
rescue Excon::Errors::InternalServerError => error
raise InternalServerError.slurp(error, self)
rescue Excon::Errors::HTTPStatusError => error
raise ServiceError.slurp(error, self)
end
def authenticate(options={})
super({
:rackspace_api_key => @rackspace_api_key,
:rackspace_username => @rackspace_username,
:rackspace_auth_url => @rackspace_auth_url,
:connection_options => @connection_options
})
end
def service_name
:cloudServersOpenStack
end
def request_id_header
"x-compute-request-id"
end
def region
@rackspace_region
end
def endpoint_uri(service_endpoint_url=nil)
@uri = super(@rackspace_endpoint || service_endpoint_url, :rackspace_compute_url)
end
private
def setup_custom_endpoint(options)
@rackspace_endpoint = Fog::Rackspace.normalize_url(options[:rackspace_compute_url] || options[:rackspace_endpoint])
if v2_authentication?
case @rackspace_endpoint
when DFW_ENDPOINT
@rackspace_endpoint = nil
@rackspace_region = :dfw
when ORD_ENDPOINT
@rackspace_endpoint = nil
@rackspace_region = :ord
when LON_ENDPOINT
@rackspace_endpoint = nil
@rackspace_region = :lon
else
# we are actually using a custom endpoint
@rackspace_region = options[:rackspace_region]
end
else
#if we are using auth1 and the endpoint is not set, default to DFW_ENDPOINT for historical reasons
@rackspace_endpoint ||= DFW_ENDPOINT
end
end
def deprecation_warnings(options)
Fog::Logger.deprecation("The :rackspace_endpoint option is deprecated. Please use :rackspace_compute_url for custom endpoints") if options[:rackspace_endpoint]
if [DFW_ENDPOINT, ORD_ENDPOINT, LON_ENDPOINT].include?(@rackspace_endpoint) && v2_authentication?
regions = @identity_service.service_catalog.display_service_regions(service_name)
Fog::Logger.deprecation("Please specify region using :rackspace_region rather than :rackspace_endpoint. Valid regions for :rackspace_region are #{regions}.")
end
end
def append_tenant_v1(credentials)
account_id = credentials['X-Server-Management-Url'].match(/.*\/([\d]+)$/)[1]
endpoint = @rackspace_endpoint || credentials['X-Server-Management-Url'] || DFW_ENDPOINT
@uri = URI.parse(endpoint)
@uri.path = "#{@uri.path}/#{account_id}"
end
def authenticate_v1(options)
credentials = Fog::Rackspace.authenticate(options, @connection_options)
append_tenant_v1 credentials
@auth_token = credentials['X-Auth-Token']
end
end
end
end
end

147
lib/fog/rackspace/core.rb Normal file
Просмотреть файл

@ -0,0 +1,147 @@
require 'fog/core'
require 'fog/json'
require 'fog/rackspace/mock_data'
require 'fog/rackspace/service'
require 'fog/rackspace/errors'
module Fog
module Rackspace
extend Fog::Provider
US_AUTH_ENDPOINT = 'https://identity.api.rackspacecloud.com/v2.0' unless defined? US_AUTH_ENDPOINT
UK_AUTH_ENDPOINT = 'https://lon.identity.api.rackspacecloud.com/v2.0' unless defined? UK_AUTH_ENDPOINT
module Errors
class ServiceError < Fog::Errors::Error
attr_reader :response_data, :status_code, :transaction_id
def to_s
status = status_code ? "HTTP #{status_code}" : "HTTP <Unknown>"
"[#{status} | #{transaction_id}] #{super}"
end
def self.slurp(error, service=nil)
data = nil
message = nil
status_code = nil
if error.response
status_code = error.response.status
unless error.response.body.empty?
begin
data = Fog::JSON.decode(error.response.body)
message = extract_message(data)
rescue => e
Fog::Logger.warning("Received exception '#{e}' while decoding>> #{error.response.body}")
message = error.response.body
data = error.response.body
end
end
end
new_error = super(error, message)
new_error.instance_variable_set(:@response_data, data)
new_error.instance_variable_set(:@status_code, status_code)
new_error.set_transaction_id(error, service)
new_error
end
def set_transaction_id(error, service)
return unless service && service.respond_to?(:request_id_header) && error.response
@transaction_id = error.response.headers[service.request_id_header]
end
def self.extract_message(data)
if data.is_a?(Hash)
message = data.values.first['message'] if data.values.first.is_a?(Hash)
message ||= data['message']
end
message || data.inspect
end
end
class InternalServerError < ServiceError; end
class Conflict < ServiceError; end
class ServiceUnavailable < ServiceError; end
class MethodNotAllowed < ServiceError; end
class BadRequest < ServiceError
attr_reader :validation_errors
def to_s
"#{super} - #{validation_errors}"
end
def self.slurp(error, service=nil)
new_error = super(error)
unless new_error.response_data.nil? or new_error.response_data['badRequest'].nil?
new_error.instance_variable_set(:@validation_errors, new_error.response_data['badRequest']['validationErrors'])
end
status_code = error.response ? error.response.status : nil
new_error.instance_variable_set(:@status_code, status_code)
new_error.set_transaction_id(error, service)
new_error
end
end
end
service(:auto_scale, 'AutoScale')
service(:block_storage, 'BlockStorage')
service(:cdn, 'CDN')
service(:compute, 'Compute')
service(:compute_v2, 'Compute v2')
service(:dns, 'DNS')
service(:storage, 'Storage')
service(:load_balancers, 'LoadBalancers')
service(:identity, 'Identity')
service(:databases, 'Databases')
service(:monitoring, 'Monitoring')
service(:queues, 'Queues')
service(:networking, 'Networking')
def self.authenticate(options, connection_options = {})
rackspace_auth_url = options[:rackspace_auth_url]
rackspace_auth_url ||= options[:rackspace_endpoint] == Fog::Compute::RackspaceV2::LON_ENDPOINT ? UK_AUTH_ENDPOINT : US_AUTH_ENDPOINT
url = rackspace_auth_url.match(/^https?:/) ? \
rackspace_auth_url : 'https://' + rackspace_auth_url
uri = URI.parse(url)
connection = Fog::Core::Connection.new(url, false, connection_options)
@rackspace_api_key = options[:rackspace_api_key]
@rackspace_username = options[:rackspace_username]
response = connection.request({
:expects => [200, 204],
:headers => {
'X-Auth-Key' => @rackspace_api_key,
'X-Auth-User' => @rackspace_username
},
:method => 'GET',
:path => (uri.path and not uri.path.empty?) ? uri.path : 'v1.0'
})
response.headers.reject do |key, value|
!['X-Server-Management-Url', 'X-Storage-Url', 'X-CDN-Management-Url', 'X-Auth-Token'].include?(key)
end
end
def self.json_response?(response)
return false unless response && response.headers
response.get_header('Content-Type') =~ %r{application/json}i ? true : false
end
def self.normalize_url(endpoint)
return nil unless endpoint
str = endpoint.chomp " "
str = str.chomp "/"
str.downcase
end
# CGI.escape, but without special treatment on spaces
def self.escape(str,extra_exclude_chars = '')
# '-' is a special character inside a regex class so it must be first or last.
# Add extra excludes before the final '-' so it always remains trailing, otherwise
# an unwanted range is created by mistake.
str.gsub(/([^a-zA-Z0-9_.#{extra_exclude_chars}-]+)/) do
'%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
end
end
end
end

Просмотреть файл

@ -0,0 +1,164 @@
require 'fog/rackspace/core'
module Fog
module Rackspace
class Databases < Fog::Service
include Fog::Rackspace::Errors
class ServiceError < Fog::Rackspace::Errors::ServiceError; end
class InternalServerError < Fog::Rackspace::Errors::InternalServerError; end
class BadRequest < Fog::Rackspace::Errors::BadRequest; end
DFW_ENDPOINT = 'https://dfw.databases.api.rackspacecloud.com/v1.0'
LON_ENDPOINT = 'https://lon.databases.api.rackspacecloud.com/v1.0'
ORD_ENDPOINT = 'https://ord.databases.api.rackspacecloud.com/v1.0'
requires :rackspace_api_key, :rackspace_username
recognizes :rackspace_auth_url
recognizes :rackspace_auth_token
recognizes :rackspace_endpoint
recognizes :rackspace_region
recognizes :rackspace_database_url
model_path 'fog/rackspace/models/databases'
model :flavor
collection :flavors
model :instance
collection :instances
model :database
collection :databases
model :user
collection :users
request_path 'fog/rackspace/requests/databases'
request :list_flavors
request :get_flavor
request :list_instances
request :get_instance
request :create_instance
request :delete_instance
request :check_root_user
request :enable_root_user
request :restart_instance
request :resize_instance
request :resize_instance_volume
request :list_databases
request :create_database
request :delete_database
request :list_users
request :create_user
request :delete_user
request :grant_user_access
request :revoke_user_access
class Mock < Fog::Rackspace::Service
def request(params)
Fog::Mock.not_implemented
end
end
class Real < Fog::Rackspace::Service
def service_name
:cloudDatabases
end
def region
@rackspace_region
end
def initialize(options = {})
@rackspace_api_key = options[:rackspace_api_key]
@rackspace_username = options[:rackspace_username]
@rackspace_auth_url = options[:rackspace_auth_url]
@rackspace_must_reauthenticate = false
@connection_options = options[:connection_options] || {}
setup_custom_endpoint(options)
authenticate
deprecation_warnings(options)
@persistent = options[:persistent] || false
@connection = Fog::Core::Connection.new(endpoint_uri.to_s, @persistent, @connection_options)
end
def request(params, parse_json = true)
super
rescue Excon::Errors::NotFound => error
raise NotFound.slurp(error, self)
rescue Excon::Errors::BadRequest => error
raise BadRequest.slurp(error, self)
rescue Excon::Errors::InternalServerError => error
raise InternalServerError.slurp(error, self)
rescue Excon::Errors::HTTPStatusError => error
raise ServiceError.slurp(error, self)
end
def endpoint_uri(service_endpoint_url=nil)
@uri = super(@rackspace_endpoint || service_endpoint_url, :rackspace_database_url)
end
def authenticate(options={})
super({
:rackspace_api_key => @rackspace_api_key,
:rackspace_username => @rackspace_username,
:rackspace_auth_url => @rackspace_auth_url,
:connection_options => @connection_options
})
end
private
def setup_custom_endpoint(options)
@rackspace_endpoint = Fog::Rackspace.normalize_url(options[:rackspace_database_url] || options[:rackspace_endpoint])
if v2_authentication?
case @rackspace_endpoint
when DFW_ENDPOINT
@rackspace_endpoint = nil
@rackspace_region = :dfw
when ORD_ENDPOINT
@rackspace_endpoint = nil
@rackspace_region = :ord
when LON_ENDPOINT
@rackspace_endpoint = nil
@rackspace_region = :lon
else
# we are actually using a custom endpoint
@rackspace_region = options[:rackspace_region]
end
else
#if we are using auth1 and the endpoint is not set, default to DFW_ENDPOINT for historical reasons
@rackspace_endpoint ||= DFW_ENDPOINT
end
end
def deprecation_warnings(options)
Fog::Logger.deprecation("The :rackspace_endpoint option is deprecated. Please use :rackspace_database_url for custom endpoints") if options[:rackspace_endpoint]
if [DFW_ENDPOINT, ORD_ENDPOINT, LON_ENDPOINT].include?(@rackspace_endpoint) && v2_authentication?
regions = @identity_service.service_catalog.display_service_regions(service_name)
Fog::Logger.deprecation("Please specify region using :rackspace_region rather than :rackspace_endpoint. Valid region for :rackspace_region are #{regions}.")
end
end
def append_tenant_v1(credentials)
account_id = credentials['X-Server-Management-Url'].match(/.*\/([\d]+)$/)[1]
endpoint = @rackspace_endpoint || credentials['X-Server-Management-Url'] || DFW_ENDPOINT
@uri = URI.parse(endpoint)
@uri.path = "#{@uri.path}/#{account_id}"
end
def authenticate_v1(options)
credentials = Fog::Rackspace.authenticate(options, @connection_options)
append_tenant_v1 credentials
@auth_token = credentials['X-Auth-Token']
end
end
end
end
end

172
lib/fog/rackspace/dns.rb Normal file
Просмотреть файл

@ -0,0 +1,172 @@
require 'fog/rackspace/core'
module Fog
module DNS
class Rackspace < Fog::Service
include Fog::Rackspace::Errors
class ServiceError < Fog::Rackspace::Errors::ServiceError; end
class InternalServerError < Fog::Rackspace::Errors::InternalServerError; end
class BadRequest < Fog::Rackspace::Errors::BadRequest; end
class Conflict < Fog::Rackspace::Errors::Conflict; end
class ServiceUnavailable < Fog::Rackspace::Errors::ServiceUnavailable; end
class CallbackError < Fog::Errors::Error
attr_reader :response, :message, :details
def initialize(response)
@response = response
@message = response.body['error']['message']
@details = response.body['error']['details']
end
end
US_ENDPOINT = 'https://dns.api.rackspacecloud.com/v1.0'
UK_ENDPOINT = 'https://lon.dns.api.rackspacecloud.com/v1.0'
requires :rackspace_api_key, :rackspace_username
recognizes :rackspace_auth_url, :rackspace_auth_token, :rackspace_dns_endpoint, :rackspace_dns_url, :rackspace_region
model_path 'fog/rackspace/models/dns'
model :record
collection :records
model :zone
collection :zones
request_path 'fog/rackspace/requests/dns'
#TODO - Import/Export, modify multiple domains, modify multiple records
request :callback
request :list_domains
request :list_domain_details
request :modify_domain
request :create_domains
request :remove_domain
request :remove_domains
request :list_subdomains
request :list_records
request :list_record_details
request :modify_record
request :remove_record
request :remove_records
request :add_records
class Mock < Fog::Rackspace::Service
def initialize(options={})
@rackspace_api_key = options[:rackspace_api_key]
@rackspace_username = options[:rackspace_username]
@rackspace_auth_url = options[:rackspace_auth_url]
@connection_options = options[:connection_options] || {}
end
def self.data
@data ||= {
}
end
def self.reset
@data = nil
end
def data
self.class.data
end
def reset_data
self.class.reset
end
end
class Real < Fog::Rackspace::Service
def service_name
:cloudDNS
end
def region
#Note: DNS does not currently support multiple regions
@rackspace_region
end
def initialize(options={})
@rackspace_api_key = options[:rackspace_api_key]
@rackspace_username = options[:rackspace_username]
@rackspace_auth_url = options[:rackspace_auth_url]
@connection_options = options[:connection_options] || {}
@rackspace_endpoint = Fog::Rackspace.normalize_url(options[:rackspace_dns_url] || options[:rackspace_dns_endpoint])
@rackspace_region = options[:rackspace_region]
authenticate
deprecation_warnings(options)
@persistent = options[:persistent] || false
@connection = Fog::Core::Connection.new(endpoint_uri.to_s, @persistent, @connection_options)
end
def endpoint_uri(service_endpoint_url=nil)
@uri = super(@rackspace_endpoint || service_endpoint_url, :rackspace_dns_url)
end
private
def request(params, parse_json = true)
super
rescue Excon::Errors::NotFound => error
raise NotFound.slurp(error, self)
rescue Excon::Errors::BadRequest => error
raise BadRequest.slurp(error, self)
rescue Excon::Errors::InternalServerError => error
raise InternalServerError.slurp(error, self)
rescue Excon::Errors::ServiceUnavailable => error
raise ServiceUnavailable.slurp(error, self)
rescue Excon::Errors::Conflict => error
raise Conflict.slurp(error, self)
rescue Excon::Errors::HTTPStatusError => error
raise ServiceError.slurp(error, self)
end
def array_to_query_string(arr)
return "" unless arr
query_array = arr.map do | k, v |
val_str = v.is_a?(Array) ? v.join(",") : v.to_s
"#{k}=#{val_str}"
end
query_array.join('&')
end
def validate_path_fragment(name, fragment)
if fragment.nil? or fragment.to_s.empty?
raise ArgumentError.new("#{name} cannot be null or empty")
end
end
private
def deprecation_warnings(options)
Fog::Logger.deprecation("The :rackspace_dns_endpoint option is deprecated. Please use :rackspace_dns_url for custom endpoints") if options[:rackspace_dns_endpoint]
end
def setup_endpoint(credentials)
account_id = credentials['X-Server-Management-Url'].match(/.*\/([\d]+)$/)[1]
@uri = URI.parse(@rackspace_endpoint || US_ENDPOINT)
@uri.path = "#{@uri.path}/#{account_id}"
end
def authenticate_v1(options)
credentials = Fog::Rackspace.authenticate(options, @connection_options)
setup_endpoint credentials
@auth_token = credentials['X-Auth-Token']
end
def authenticate(options={})
super({
:rackspace_api_key => @rackspace_api_key,
:rackspace_username => @rackspace_username,
:rackspace_auth_url => @rackspace_auth_url,
:connection_options => @connection_options
})
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,503 @@
#Auto Scale (AutoScale)
This document explains how to get started using Auto Scale with Fog. It assumes you have read the [Getting Started with Fog and the Rackspace Open Cloud](getting_started.md) document.
## Basic Concepts
Auto Scale is a service that enables you to scale your application by adding or removing servers based on monitoring events, a schedule, or arbitrary webhooks.
Auto Scale functions by linking three services:
* Monitoring (such as Monitoring as a Service)
* Auto Scale
* Servers and Load Balancers
## Workflow
A scaling group is monitored by Rackspace Cloud Monitoring. When Monitoring triggers an alarm for high utilization within the Autoscaling group, a webhook is triggered. The webhook calls the Auto Scale service, which consults a policy in accordance with the webhook. The policy determines how many additional Cloud Servers should be added or removed in accordance with the alarm.
Alarms may trigger scaling up or scaling down. Scale-down events always remove the oldest server in the group.
Cooldowns allow you to ensure that you don't scale up or down too fast. When a scaling policy runs, both the scaling policy cooldown and the group cooldown start. Any additional requests to the group are discarded while the group cooldown is active. Any additional requests to the specific policy are discarded when the policy cooldown is active.
It is important to remember that Auto Scale does not configure anything within a server. This means that all images should be self-provisioning. It is up to you to make sure that your services are configured to function properly when the server is started. We recommend using something like Chef, Salt, or Puppet.
## Starting irb console
Start by executing the following command:
irb
Once `irb` has launched you need to require the Fog library.
If using Ruby 1.8.x execute:
require 'rubygems'
require 'fog'
If using Ruby 1.9.x execute:
require 'fog'
## Create Service
Next, create a connection to Auto Scale:
Using a US-based account:
service = Fog::Rackspace::AutoScale.new (
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:rackspace_region => :ord,
:connection_options => {} # Optional
)
Using a UK-based account:
service = Fog::Rackspace::AutoScale.new (
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT,
:rackspace_region => :lon,
:connection_options => {} # Optional
)
To learn more about obtaining cloud credentials refer to the [Getting Started with Fog and the Rackspace Open Cloud](getting_started.md) document.
By default `Fog::Rackspace::AutoScale` will authenticate against the US authentication endpoint. You can specify alternative authentication endpoints using the key `:rackspace_auth_url`. Please refer to [Alternate Authentication Endpoints](http://docs.rackspace.com/auth/api/v2.0/auth-client-devguide/content/Endpoints-d1e180.html) for a list of alternative Rackspace authentication endpoints.
Alternative regions are specified using the key `:rackspace_region `. A list of regions available for Auto Scale can be found by executing the following:
identity_service = Fog::Identity.new({
:provider => 'Rackspace', # Rackspace Fog provider
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT # Not specified for US Cloud
})
identity_service.service_catalog.display_service_regions :autoscale
Rackspace Private Cloud installations can skip specifying a region and directly specify their custom service endpoints using the key `:rackspace_auto_scale_url`.
**Note**: A`Fog::Rackspace::AutoScale` instance is needed for the desired region.
### Optional Connection Parameters
Fog supports passing additional connection parameters to its underlying HTTP library (Excon) using the `:connection_options` parameter.
<table>
<tr>
<th>Key</th>
<th>Description</th>
</tr>
<tr>
<td>:connect_timeout</td>
<td>Connection timeout (default: 60 seconds)</td>
</tr>
<tr>
<td>:read_timeout</td>
<td>Read timeout for connection (default: 60 seconds)</td> </tr>
<tr>
<td>:write_timeout</td>
<td>Write timeout for connection (default: 60 seconds)</td>
</tr>
<tr>
<td>:proxy</td>
<td>Proxy for HTTP and HTTPS connections</td>
</tr>
<tr>
<td>:ssl_ca_path</td>
<td>Path to SSL certificate authorities</td>
</tr>
<tr>
<td>:ssl_ca_file</td>
<td>SSL certificate authority file</td>
</tr>
<tr>
<td>:ssl_verify_peer</td>
<td>SSL verify peer (default: true)</td>
</tr>
</table>
## Fog Abstractions
Fog provides both a **model** and **request** abstraction. The request abstraction provides the most efficient interface and the model abstraction wraps the request abstraction to provide a convenient `ActiveModel`-like interface.
### Request Layer
The request abstraction maps directly to the [Auto Scale API](http://docs.rackspace.com//cas/api/v1.0/autoscale-devguide/content/API_Operations.html). It provides the most efficient interface to the Rackspace Open Cloud.
To see a list of requests supported by the service:
service.requests
This returns:
:list_groups, :create_group, :get_group, :delete_group, :get_group_state, :pause_group_state, :resume_group_state, :get_group_config, :update_group_config, :get_launch_config, :update_launch_config, :list_policies, :create_policy, :get_policy, :update_policy, :delete_policy, :execute_policy, :execute_anonymous_webhook, :get_webhook, :list_webhooks, :create_webhook, :update_webhook, :delete_webhook
#### Example Request
To request a list of Auto Scale groups:
response = service.list_groups
This returns in the following `Excon::Response`:
#<Excon::Response:0x007fd3ea78af08 @data={:body=>{"groups_links"=>[], "groups"=>[{"paused"=>false, "desiredCapacity"=>0, "links"=>[{"href"=>"https://ord.autoscale.api.rackspacecloud.com/v1.0/555/groups/b45e6107-26ca-4a93-869d-46bf20005df3/", "rel"=>"self"}], "active"=>[], "pendingCapacity"=>0, "activeCapacity"=>0, "id"=>"b45e6107-26ca-4a93-869d-46bf20005df3", "name"=>"fog-scailing-group"}]}, :headers=>{"Content-Type"=>"application/json", "Via"=>"1.1 Repose (Repose/2.8.2)", "x-response-id"=>"4c2a8f70-a7da-479a-bf69-6882b5b6346e", "Date"=>"Fri, 27 Sep 2013 15:38:10 GMT", "Transfer-Encoding"=>"chunked", "Server"=>"Jetty(8.0.y.z-SNAPSHOT)"}, :status=>200, :remote_ip=>"162.209.41.103"}, @body="{\"groups_links\": [], \"groups\": [{\"paused\": false, \"desiredCapacity\": 0, \"links\": [{\"href\": \"https://ord.autoscale.api.rackspacecloud.com/v1.0/555/groups/b45e6107-26ca-4a93-869d-46bf20005df3/\", \"rel\": \"self\"}], \"active\": [], \"pendingCapacity\": 0, \"activeCapacity\": 0, \"id\": \"b45e6107-26ca-4a93-869d-46bf20005df3\", \"name\": \"fog-scailing-group\"}]}", @headers={"Content-Type"=>"application/json", "Via"=>"1.1 Repose (Repose/2.8.2)", "x-response-id"=>"4c2a8f70-a7da-479a-bf69-6882b5b6346e", "Date"=>"Fri, 27 Sep 2013 15:38:10 GMT", "Transfer-Encoding"=>"chunked", "Server"=>"Jetty(8.0.y.z-SNAPSHOT)"}, @status=200, @remote_ip="162.209.41.103">
To view the status of the response:
response.status
**Note**: Fog is aware of valid HTTP response statuses for each request type. If an unexpected HTTP response status occurs, Fog will raise an exception.
To view response body:
response.body
returns:
{"groups_links"=>[], "groups"=>[{"paused"=>false, "desiredCapacity"=>0, "links"=>[{"href"=>"https://ord.autoscale.api.rackspacecloud.com/v1.0/555/groups/b45e6107-26ca-4a93-869d-46bf20005df3/", "rel"=>"self"}], "active"=>[], "pendingCapacity"=>0, "activeCapacity"=>0, "id"=>"b45e6107-26ca-4a93-869d-46bf20005df3", "name"=>"fog-scailing-group"}]}
To learn more about Auto Scale request methods refer to [rdoc](http://rubydoc.info/gems/fog/Fog/Rackspace/AutoScale/Real). To learn more about Excon refer to [Excon GitHub repo](https://github.com/geemus/excon).
### Model Layer
Fog models behave in a manner similar to `ActiveModel`. Models will generally respond to `create`, `save`, `persisted?`, `destroy`, `reload` and `attributes` methods. Additionally, fog will automatically create attribute accessors.
Here is a summary of common model methods:
<table>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
<tr>
<td>create</td>
<td>
Accepts hash of attributes and creates object.<br>
Note: creation is a non-blocking call and you will be required to wait for a valid state before using resulting object.
</td>
</tr>
<tr>
<td>save</td>
<td>Saves object.<br>
Note: not all objects support updating object.</td>
</tr>
<tr>
<td>persisted?</td>
<td>Returns true if the object has been persisted.</td>
</tr>
<tr>
<td>destroy</td>
<td>
Destroys object.<br>
Note: this is a non-blocking call and object deletion might not be instantaneous.
</td>
<tr>
<td>reload</td>
<td>Updates object with latest state from service.</td>
<tr>
<td>ready?</td>
<td>Returns true if object is in a ready state and able to perform actions. This method will raise an exception if object is in an error state.</td>
</tr>
<tr>
<td>attributes</td>
<td>Returns a hash containing the list of model attributes and values.</td>
</tr>
<td>identity</td>
<td>
Returns the identity of the object.<br>
Note: This might not always be equal to object.id.
</td>
</tr>
<tr>
<td>wait_for</td>
<td>This method periodically reloads model and then yields to specified block until block returns true or a timeout occurs.</td>
</tr>
</table>
The remainder of this document details the model abstraction.
## The Scaling Group
* The **Scaling Group** is the basic unit of automatic scaling. It determines the minimum and maximum number of servers that exist at any time for the group, the cooldown period between scaling events, the configuration for each new server, the load balancer to add these servers to (optional), and any policies that are used for this group.
### List Scaling Groups
To retrieve the list of your scaling groups:
service.groups
This returns a collection of `Fog::Rackspace::AutoScale::Group` objects:
<Fog::Rackspace::AutoScale::Groups
[
<Fog::Rackspace::AutoScale::Group
id="b45e6107-26ca-4a93-869d-46bf20005df3",
links=[{"href"=>"https://ord.autoscale.api.rackspacecloud.com/v1.0/555/groups/b45e6107-26ca-4a93-869d-46bf20005df3/", "rel"=>"self"}]
>
]
>
To view the [launch configuration](#launch-configurations) for a group execute the following:
groups = service.groups
group = group.first
group.launch_config
This returns a `Fog::Rackspace::AutoScale::LaunchConfig`:
<Fog::Rackspace::AutoScale::LaunchConfig
group= <Fog::Rackspace::AutoScale::Group
id="b45e6107-26ca-4a93-869d-46bf20005df3",
links=[{"href"=>"https://ord.autoscale.api.rackspacecloud.com/v1.0/5555/groups/b45e6107-26ca-4a93-869d-46bf20005df3/", "rel"=>"self"}]
>,
type="launch_server",
args={"loadBalancers"=>[{"port"=>8080, "loadBalancerId"=>9099}], "server"=>{"name"=>"autoscale_server", "imageRef"=>"0d589460-f177-4b0f-81c1-8ab8903ac7d8", "flavorRef"=>"2", "OS-DCF =>diskConfig"=>"AUTO", "metadata"=>{"build_config"=>"core", "meta_key_1"=>"meta_value_1", "meta_key_2"=>"meta_value_2"}, "networks"=>[{"uuid"=>"11111111-1111-1111-1111-111111111111"}, {"uuid"=>"00000000-0000-0000-0000-000000000000"}], "personality"=>[{"path"=>"/root/.csivh", "contents"=>"VGhpcyBpcyBhIHRlc3QgZmlsZS4="}]}}
>
### Getting the Current State of a Scaling Group
It is sometimes helpful to determine what the current state of a scaling group is in terms of whether it is scaling up, scaling down, or stable.
To see your group's current state execute the following:
group.state
This returns the following:
{"paused"=>false, "desiredCapacity"=>0, "links"=>[{"href"=>"https://ord.autoscale.api.rackspacecloud.com/v1.0/555/groups/b45e6107-26ca-4a93-869d-46bf20005df3/", "rel"=>"self"}], "active"=>[], "pendingCapacity"=>0, "activeCapacity"=>0, "id"=>"b45e6107-26ca-4a93-869d-46bf20005df3", "name"=>"fog-scailing-group"}
The `active` key holds a list of the IDs of the servers created as part of this scaling group. The `paused` key shows whether or not the scaling group's response to alarms is active or not. There are 3 'capacity'-related keys: `activeCapacity`, `desiredCapacity`, and `pendingCapacity`:
Key | Represents
---- | ----
**activeCapacity** | The number of active servers that are part of this scaling group
**desiredCapacity** | The target number of servers for this scaling group, based on the combination of configuration settings and monitoring alarm responses
**pendingCapacity** | The number of servers which are in the process of being created (when positive) or destroyed (when negative).
### Pausing a Scaling Group's Policies
To pause a scaling group's execution:
group.pause
There is a corresponding `resume` method to resume execution:
group.resume
### Creating a Scaling Group
There are many options available to you when creating a scaling group. In order to ease the burden, a builder is provided.
To create a scaling group with the builder you first include the builder in your script:
require 'fog/rackspace/models/auto_scale/group_builder'
And then use the builder as follows:
INTERNET = '00000000-0000-0000-0000-000000000000'
SERVICE_NET = '11111111-1111-1111-1111-111111111111'
attributes = {
:server_name => "testgroup",
:image => my_image,
:flavor => 3,
:networks => [INTERNET, SERVICE_NET],
:personality => [
{
"path" => "/root/.csivh",
"contents" => "VGhpcyBpcyBhIHRlc3QgZmlsZS4="
}
],
:max_entities => 3,
:min_entities => 2,
:cooldown => 600,
:name => "MyScalingGroup",
:metadata => { "created_by" => "autoscale sample script" },
:load_balancers => {
:port => 80,
:loadBalancerId => 1234
}
:launch_config_type => :launch_server
}
group = Fog::Rackspace::AutoScale::GroupBuilder.build(service, attributes)
group.save
This creates the scaling group with the name `MyScalingGroup`, and returns a `Fog::Rackspace::AutoScale::Group` object representing the new group. Since the `:min_entities` is 2, it immediately creates 2 servers for the group, based on the image whose ID is in the variable `my_image`. When they are created, they are then added to the load balancer whose ID is `1234`, and receive requests on port 80.
Note that the `:server_name` parameter represents a base string to which Autoscale prepends a 10-character prefix to create a unique name for each server. The prefix always begins with 'as' and is followed by 8 random hex digits and a dash (-). For example, if you set the server_name to 'testgroup', and the scaling group creates 3 servers, their names would look like these:
as5defddd4-testgroup
as92e512fe-testgroup
asedcf7587-testgroup
**Note**: You will see need to add policies to trigger auto scaling operations. See [Policies Section](#policies) for more information.
#### Parameters
Parameter | Required | Default | Notes
---- | ---- | ---- | ----
**:name** | yes | |
**:cooldown** | yes | | Period in seconds after a scaling event in which further events are ignored
**:min_entities** | yes | |
**:max_entities** | yes | |
**:launch_config_type** | yes | | Only option currently is`:launch_server`
**:flavor** | yes | | Flavor to use for each server that is launched. This can be a `Fog::Compute::RackspaceV2::Flavor` or an ID.
**:server_name** | yes | | The base name for servers created by Autoscale.
**:image** | yes | | This can be a `Fog::Compute::RackspaceV2::Image` or an id. This is the image that all new servers are created from.
**:disk_config** | no | MANUAL | Determines if the server's disk is partitioned to the full size of the flavor ('AUTO') or just to the size of the image ('MANUAL').
**:server_metadata** | no | | Arbitrary key-value pairs you want to associate with your servers.
**:personality** | no | | Small text files that are created on the new servers. _Personality_ is discussed in the [Rackspace Cloud Servers documentation](http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Server_Personality-d1e2543.html)
**:networks** | no | | Any array of networks to which you want to attach new servers. See the [Create Servers documentation](http://docs.rackspace.com/servers/api/v2/cs-devguide/content/CreateServers.html) for standard network IDs.
**:load_balancers** | no | | Either a hash of {:port, :loadBalancerId} or a `Fog::Rackspace::LoadBalancers::LoadBalancer` object.
### Updating a Scaling Configuration Group
A group's scaling configuration can be updated via the `Fog::Rackspace::AutoScale::GroupConfig` object. You can retrieve this object by executing the following:
group_config = group.group_config
Available options on `group_config` include `:max_entities`, `:name`, `:cooldown`, `:min_entities`, `:metadata`. To update a scaling group, pass one or more of these as keyword arguments. For example, to change the cooldown period to 2 minutes and increase the maximum entities to 16, you call:
group_config.cooldown = 120
group_config.max_entities = 16
group_config.save
**Note**: If you pass any metadata values in this call, it must be the full set of metadata for the scaling group, since the underlying API call **overwrites** any existing metadata.
### Deleting a Scaling Group
To remove a scaling group, call its `destroy` method:
group.destroy
Note: you cannot delete a scaling group that has active servers in it. You must first delete the servers by setting the `min_entities` and `max_entities` to zero:
group_config = group.group_config
group_config.min_entities = 0
group_config.max_entities = 0
group_config.save
Once the servers are deleted you can then delete the scaling group.
## Launch Configurations
Each scaling group has an associated **launch configuration**. This determines the properties of servers that are created in response to a scaling event.
The `:server_name` represents a base string to which Autoscale prepends a 10-character prefix. The prefix always begins with 'as' and is followed by 8 random hex digits and a dash (-). For example, if you set the `server_name` to 'testgroup', and the scaling group creates 3 servers, their names would look like these:
as5defddd4-testgroup
as92e512fe-testgroup
asedcf7587-testgroup
To retrieve the launch config:
launch_config = group.launch_config
The launch configuration contains two attributes `:type` and `:args`. The only launch type currently available for Auto Scale is `:launch_server`. The `args` attribute contains a hash with the launch server configuration options as follows:
{"server"=>{
"name"=>"autoscale_server",
"imageRef"=>"66448837-1a58-4bd2-a647-9f3272f36263",
"flavorRef"=>"2",
"networks"=>[{"uuid"=>"00000000-0000-0000-0000-000000000000"}, {"uuid"=>"11111111-1111-1111-1111-111111111111"}],
"personality"=>[{"path"=>"/root/.csivh", "contents"=>"VGhpcyBpcyBhIHRlc3QgZmlsZS4="}],
"OS-DCF =>diskConfig"=>"MANUAL",
"metadata"=>{}}}
Changes to the args attribute can be saved by executing the `save` method on the `launch_config`. For example if you wanted to change the disk configuration to `AUTO`, you would do the following:
launch_config.args["server"]["OS-DCF =>diskConfig"] = "AUTO"
launch_config.save
**Note**: If you pass any metadata values in this call, it must be the full set of metadata for the launch configuration, since the underlying API call **overwrites** any existing metadata.
## Policies
When an alarm is triggered in Cloud Monitoring, it calls the webhook associated with a particular policy. The policy is designed to update the scaling group to increase or decrease the number of servers in response to the particular alarm.
To list the policies for a given scaling group use the following:
policies = group.policies
### Creating a Policy
To add a policy to a scaling group use the following:
group.policies.create :name => 'Scale by one server', :cooldown => 360, :type => 'webhook', :change => 1
#### Parameters
Parameter | Required | Default | Notes
---- | ---- | ---- | ----
**:name** | yes | |
**:type** | yes | | This can be "webhook", "schedule" or "cloud monitoring"
**:cooldown** | yes | | Period in seconds after a policy execution in which further events are ignored. This is separate from the overall cooldown for the scaling group.
**:change** | no | | Can be positive or negative, which makes this a scale-up or scale-down policy, respectively. If this value is specified you can not specify `:change_percent`.
**:change_percent** | no | | The percentage change to the autoscale group's number of units. If this value is specified you can not specify `:change`.
**:args** | no | | This is used to specify schedule parameters. Please refer to [Policy documentation](http://docs-internal-staging.rackspace.com/cas/api/v1.0/autoscale-devguide/content/POST_createPolicies_v1.0__tenantId__groups__groupId__policies_Policies.html) for more information.
### Updating a Policy
You may update a policy at any time, passing in any or all of the above parameters to change that value. For example, to change the cooldown to 60 seconds, and the number of servers to remove to 3, call:
policy.cooldown = 60
policy.change = 3
policy.save
### Executing a Policy
You don't need to wait for an alarm to be triggered in Cloud Monitoring in order to execute a particular policy. If desired, you may do so manually by calling the policy's `execute` method:
policy.execute
### Deleting a Policy
To remove a policy, call its `destroy` method:
policy.destroy
## Webhooks
When an alarm is triggered in Cloud Monitoring, it calls the associated webhook, which in turn causes the policy for that webhook to be executed.
To list the webhooks for a given policy:
webhooks = policy.webhooks
### Creating a Webhook
To add a webhook to a policy:
webhook = policy.webhooks.create :name => 'my-webhook'
The `:name` parameter is required; the `:metadata` parameter is optional. You can retrieve the webhook by executing:
webhook.execution_url
### Updating a Webhook
You may update a webhook at any time to change either its name or its metadata:
webhook.name = 'webhook1'
webhook.metadata = {
:owner => 'webteam'
}
webhook.save
**Note**: If you pass any metadata values in this call, it must be the full set of metadata for the Webhook, since the underlying API call **overwrites** any existing metadata.
### Deleting a webhook
When you wish to remove a webhook, call its `destroy` method:
webhook.destroy

Просмотреть файл

@ -0,0 +1,417 @@
#Cloud Block Storage (BlockStorage)
This document explains how to get started using Cloud Block Storage with Fog. It assumes you have read the [Getting Started with Fog and the Rackspace Open Cloud](getting_started.md) document.
## Starting irb console
Start by executing the following command:
irb
Once `irb` has launched you need to require the Fog library.
If using Ruby 1.8.x execute:
require 'rubygems'
require 'fog'
If using Ruby 1.9.x execute:
require 'fog'
## Create Service
Next, create a connection to Cloud Block Storage:
Using a US-based account:
service = Fog::Rackspace::BlockStorage.new({
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:rackspace_region => :ord, # Defaults to :dfw
:connection_options => {} # Optional
})
Using a UK-based account:
service = Fog::Rackspace::BlockStorage.new({
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT,
:rackspace_region => :lon,
:connection_options => {} # Optional
})
To learn more about obtaining cloud credentials refer to the [Getting Started with Fog and the Rackspace Open Cloud](getting_started.md) document.
By default `Fog::Rackspace::BlockStorage` will authenticate against the US authentication endpoint and connect to the DFW region. You can specify alternative authentication endpoints using the key `:rackspace_auth_url`. Please refer to [Alternate Authentication Endpoints](http://docs.rackspace.com/auth/api/v2.0/auth-client-devguide/content/Endpoints-d1e180.html) for a list of alternative Rackspace authentication endpoints.
Alternative regions are specified using the key `:rackspace_region `. A list of regions available for Cloud Block Storage can be found by executing the following:
identity_service = Fog::Identity({
:provider => 'Rackspace', # Rackspace Fog provider
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT # Not specified for US Cloud
})
identity_service.service_catalog.display_service_regions :cloudBlockStorage
Rackspace Private Cloud installations can skip specifying a region and directly specify their custom service endpoints using the key `:rackspace_block_storage_url`.
**Note**: A`Fog::Rackspace::BlockStorage` instance is needed for the desired region.
### Optional Connection Parameters
Fog supports passing additional connection parameters to its underlying HTTP library (Excon) using the `:connection_options` parameter.
<table>
<tr>
<th>Key</th>
<th>Description</th>
</tr>
<tr>
<td>:connect_timeout</td>
<td>Connection timeout (default: 60 seconds)</td>
</tr>
<tr>
<td>:read_timeout</td>
<td>Read timeout for connection (default: 60 seconds)</td> </tr>
<tr>
<td>:write_timeout</td>
<td>Write timeout for connection (default: 60 seconds)</td>
</tr>
<tr>
<td>:proxy</td>
<td>Proxy for HTTP and HTTPS connections</td>
</tr>
<tr>
<td>:ssl_ca_path</td>
<td>Path to SSL certificate authorities</td>
</tr>
<tr>
<td>:ssl_ca_file</td>
<td>SSL certificate authority file</td>
</tr>
<tr>
<td>:ssl_verify_peer</td>
<td>SSL verify peer (default: true)</td>
</tr>
</table>
## Fog Abstractions
Fog provides both a **model** and **request** abstraction. The request abstraction provides the most efficient interface and the model abstraction wraps the request abstraction to provide a convenient `ActiveModel` like interface.
### Request Layer
The request abstraction maps directly to the [Cloud Block Storage API](http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/overview.html). It provides the most efficient interface to the Rackspace Open Cloud.
To see a list of requests supported by the service:
service.requests
This returns:
:create_volume, :delete_volume, :get_volume, :list_volumes, :get_volume_type, :list_volume_types, :create_snapshot, :delete_snapshot, :get_snapshot, :list_snapshots
#### Example Request
To request a list of volume types:
response = service.list_volume_types
This returns in the following `Excon::Response`:
<Excon::Response:0x10a708fb8 @remote_ip="72.32.164.210", @body="{\"volume_types\": [{\"extra_specs\": {}, \"name\": \"SATA\", \"id\": 1}, {\"extra_specs\": {}, \"name\": \"SSD\", \"id\": 2}]}", @status=200, @headers={"Date"=>"Mon, 18 Mar 2013 20:26:03 GMT", "Content-Length"=>"109", "Content-Type"=>"application/json", "X-Compute-Request-Id"=>"req-9c2093d4-8a41-4d8b-a069-114470d1a0dd"}, @data={:status=>200, :headers=>{"Date"=>"Mon, 18 Mar 2013 20:26:03 GMT", "Content-Length"=>"109", "Content-Type"=>"application/json", "X-Compute-Request-Id"=>"req-9c2093d4-8a41-4d8b-a069-114470d1a0dd"}, :remote_ip=>"72.32.164.210", :body=>{"volume_types"=>[{"name"=>"SATA", "id"=>1, "extra_specs"=>{}}, {"name"=>"SSD", "id"=>2, "extra_specs"=>{}}]}}>
To view the status of the response:
response.status
**Note**: Fog is aware of valid HTTP response statuses for each request type. If an unexpected HTTP response status occurs, Fog will raise an exception.
To view response body:
response.body
This will return:
{"volume_types"=>[{"name"=>"SATA", "id"=>1, "extra_specs"=>{}}, {"name"=>"SSD", "id"=>2, "extra_specs"=>{}}]}
To learn more about Cloud Block Storage request methods refer to [rdoc](http://rubydoc.info/gems/fog/Fog/Rackspace/BlockStorage/Real). To learn more about Excon refer to [Excon GitHub repo](https://github.com/geemus/excon).
### Model Layer
Fog models behave in a manner similar to `ActiveModel`. Models will generally respond to `create`, `save`, `persisted?`, `destroy`, `reload` and `attributes` methods. Additionally, fog will automatically create attribute accessors.
Here is a summary of common model methods:
<table>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
<tr>
<td>create</td>
<td>
Accepts hash of attributes and creates object.<br>
Note: creation is a non-blocking call and you will be required to wait for a valid state before using resulting object.
</td>
</tr>
<tr>
<td>save</td>
<td>Saves object.<br>
Note: not all objects support updating object.</td>
</tr>
<tr>
<td>persisted?</td>
<td>Returns true if the object has been persisted.</td>
</tr>
<tr>
<td>destroy</td>
<td>
Destroys object.<br>
Note: this is a non-blocking call and object deletion might not be instantaneous.
</td>
<tr>
<td>reload</td>
<td>Updates object with latest state from service.</td>
<tr>
<td>ready?</td>
<td>Returns true if object is in a ready state and able to perform actions. This method will raise an exception if object is in an error state.</td>
</tr>
<tr>
<td>attributes</td>
<td>Returns a hash containing the list of model attributes and values.</td>
</tr>
<td>identity</td>
<td>
Returns the identity of the object.<br>
Note: This might not always be equal to object.id.
</td>
</tr>
<tr>
<td>wait_for</td>
<td>This method periodically reloads model and then yields to specified block until block returns true or a timeout occurs.</td>
</tr>
</table>
The remainder of this document details the model abstraction.
## List Volume Types
To retrieve a list of volume types:
service.volume_types
This returns a collection of `Fog::Rackspace::BlockStorage::VolumeType` models:
<Fog::Rackspace::BlockStorage::VolumeTypes
[
<Fog::Rackspace::BlockStorage::VolumeType
id=1,
name="SATA",
extra_specs={}
>,
<Fog::Rackspace::BlockStorage::VolumeType
id=2,
name="SSD",
extra_specs={}
>
]
>
## List Volumes
To retrieve a list of volumes:
service.volumes
This returns a collection of `Fog::Rackspace::BlockStorage::Volume` models:
<Fog::Rackspace::BlockStorage::Volumes
[
<Fog::Rackspace::BlockStorage::Volume
id="a53a532f-546c-4da3-8c2d-b26be1046630",
created_at="2013-03-19T14:19:16.000000",
state="available",
display_name="fog-ssd",
display_description=nil,
size=100,
attachments=[],
volume_type="SSD",
availability_zone="nova"
>,
<Fog::Rackspace::BlockStorage::Volume
id="e2359473-9933-483f-90df-deb4a9fb25ae",
created_at="2013-03-19T14:16:45.000000",
state="available",
display_name="fog-example",
display_description=nil,
size=100,
attachments=[],
volume_type="SATA",
availability_zone="nova"
>
]
>
## Get Volume
To retrieve an individual volume:
service.volume.get "fog-example"
This returns a `Fog::Rackspace::BlockStorage::Volume`:
<Fog::Rackspace::BlockStorage::Volume
id="e2359473-9933-483f-90df-deb4a9fb25ae",
created_at="2013-03-19T14:16:45.000000",
state="available",
display_name="fog-example",
display_description=nil,
size=100,
attachments=[],
volume_type="SATA",
availability_zone="nova"
>
## Create Volume
To create a volume:
volume = service.volumes.create(:size => 100, :display_name => 'fog-ssd', :volume_type => 'SSD')
This will return a `Fog::Rackspace::BlockStorage::Volume`:
<Fog::Rackspace::BlockStorage::Volume
id="a53a532f-546c-4da3-8c2d-b26be1046630",
created_at="2013-03-19T14:19:16.000000",
state="available",
display_name="fog-ssd",
display_description=nil,
size=100,
attachments=[],
volume_type="SSD",
availability_zone="nova"
>
**Note**: The `:size` parameter is the only required parameter and is in gigabytes. Volumes must be a minimum of 100 GB.
### Additional Parameters
The `create` method also supports the following key values:
<table>
<tr>
<th>Key</th>
<th>Description</th>
</tr>
<tr>
<td>:display_name</td>
<td>The name of the volume.</td>
</tr>
<tr>
<td>:display_description</td>
<td>A description of the volume.</td>
</tr>
<tr>
<td>:snapshot_id</td>
<td>The optional snapshot from which to create a volume.</td>
</tr>
<tr>
<td>:volume_type</td>
<td>The type of volume to create. Refer to <a href="#list-volume-types">List Volume Types</a> section for valid types. SATA is the default volume type.</td>
</tr>
</table>
## Attach Volume
Please refer to the [Attach Volume](compute_v2.md#attach-volume) section in the [Next Generation Cloud Servers™ (compute_v2)](compute_v2.md) documentation.
## Detach Volume
Please refer to the [Detach Volume](compute_v2.md#detach-volume) section in the [Next Generation Cloud Servers™ (compute_v2)](compute_v2.md) documentation.
## Delete Volume
To delete a volume:
volume.destroy
**Note**: You cannot delete a volume until all of its dependent snapshots have been deleted.
## List Snapshots
To retrieve a list of snapshots:
service.snapshots
To retrieve a list of snapshots for a given volume:
volume.snapshots
## Create Snapshot
A snapshot is a point-in-time copy of a volume. Each subsequent snapshot will be the difference between the previous snapshot and the current volume.
To create a snapshot of a given volume:
volume.create_snapshot :display_name => 'initial-snapshot'
**Note**: All writes to the volume should be flushed before creating the snapshot, either by unmounting any file systems on the volume or by detaching the volume.
### Additional Parameters
The `create_snapshot` method also supports the following key values:
<table>
<tr>
<th>Key</th>
<th>Description</th>
</tr>
<tr>
<td>:display_name</td>
<td>The name of the snapshot.</td>
</tr>
<tr>
<td>:display_description</td>
<td>A description of the snapshot.</td>
</tr>
<tr>
<td>:force</td>
<td>If set to true, snapshot will be taken even if volume is still mounted.</td>
</tr>
</table>
## Delete Snapshot
To delete a snapshot:
snapshot.destroy
## Examples
Example code using Cloud Block Storage can be found [here](https://github.com/fog/fog/tree/master/lib/fog/rackspace/examples).
## Additional Resources
* [fog.io](http://fog.io/)
* [Fog rdoc](http://rubydoc.info/gems/fog/)
* [Fog Github repo](https://github.com/fog/fog)
* [Fog Github Issues](https://github.com/fog/fog/issues)
* [Excon Github repo](https://github.com/geemus/excon)
* [Cloud Block Storage API](http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/index.html)
## Support and Feedback
Your feedback is appreciated! If you have specific issues with the **fog** SDK, you should file an [issue via Github](https://github.com/fog/fog/issues).
For general feedback and support requests, send an email to: <sdk-support@rackspace.com>.

Просмотреть файл

@ -0,0 +1,719 @@
#Next Generation Cloud Servers™ (compute_v2)
This document explains how to get started using Next Generation Cloud Servers with Fog. It assumes you have read the [Getting Started with Fog and the Rackspace Open Cloud](getting_started.md) document.
**Note**: Fog also provides an interface to First Gen Cloud Servers™ (compute). The compute interface is deprecated and should only be used if you need to interact with our first generation cloud. Fog determines the appropriate interface based on the `:version` parameter. See [Create Service](#create-service) section for more information.
## Starting irb console
Start by executing the following command:
irb
Once `irb` has launched you need to require the Fog library.
If using Ruby 1.8.x execute:
require 'rubygems'
require 'fog'
If using Ruby 1.9.x execute:
require 'fog'
## Create Service
Next, create a connection to the Next Gen Cloud Servers:
Using a US-based account:
service = Fog::Compute.new({
:provider => 'Rackspace', # Rackspace Fog provider
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:version => :v2, # Use Next Gen Cloud Servers
:rackspace_region => :ord, # Defaults to :dfw
:connection_options => {} # Optional
})
Using a UK-based account:
service = Fog::Compute.new({
:provider => 'Rackspace', # Rackspace Fog provider
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:version => :v2, # Use Next Gen Cloud Servers
:rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT,
:rackspace_region => :lon,
:connection_options => {} # Optional
})
To learn more about obtaining cloud credentials refer to the [Getting Started with Fog and the Rackspace Open Cloud](getting_started.md) document.
By default `Fog::Compute` will authenticate against the US authentication endpoint and connect to the DFW region. You can specify alternative authentication endpoints using the key `:rackspace_auth_url`. Please refer to [Alternate Authentication Endpoints](http://docs.rackspace.com/auth/api/v2.0/auth-client-devguide/content/Endpoints-d1e180.html) for a list of alternative Rackspace authentication endpoints.
Alternative regions are specified using the key `:rackspace_region `. A list of regions available for Cloud Servers can be found by executing the following:
identity_service = Fog::Identity({
:provider => 'Rackspace', # Rackspace Fog provider
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT # Not specified for US Cloud
})
identity_service.service_catalog.display_service_regions :cloudServersOpenStack
Rackspace Private Cloud installations can skip specifying a region and directly specify their custom service endpoints using the key `:rackspace_compute_url`.
**Note**: A`Fog::Compute` instance is needed for the desired region.
### Optional Connection Parameters
Fog supports passing additional connection parameters to its underlying HTTP library (Excon) using the `:connection_options` parameter.
<table>
<tr>
<th>Key</th>
<th>Description</th>
</tr>
<tr>
<td>:connect_timeout</td>
<td>Connection timeout (default: 60 seconds)</td>
</tr>
<tr>
<td>:read_timeout</td>
<td>Read timeout for connection (default: 60 seconds)</td> </tr>
<tr>
<td>:write_timeout</td>
<td>Write timeout for connection (default: 60 seconds)</td>
</tr>
<tr>
<td>:proxy</td>
<td>Proxy for HTTP and HTTPS connections</td>
</tr>
<tr>
<td>:ssl_ca_path</td>
<td>Path to SSL certificate authorities</td>
</tr>
<tr>
<td>:ssl_ca_file</td>
<td>SSL certificate authority file</td>
</tr>
<tr>
<td>:ssl_verify_peer</td>
<td>SSL verify peer (default: true)</td>
</tr>
</table>
## Fog Abstractions
Fog provides both a **model** and **request** abstraction. The request abstraction provides the most efficient interface and the model abstraction wraps the request abstraction to provide a convenient `ActiveModel` like interface.
### Request Layer
The request abstraction maps directly to the [Next Gen Cloud Servers API](http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ch_preface.html). It provides the most efficient interface to the Rackspace Open Cloud.
To see a list of requests supported by the service:
service.requests
This returns:
:list_servers, :get_server, :create_server, :update_server, :delete_server, :change_server_password, :reboot_server, :rebuild_server, :resize_server, :confirm_resize_server, :revert_resize_server, :list_images, :get_image, :list_flavors, :get_flavor, :attach_volume, :get_attachment, :list_attachments, :delete_attachment
#### Example Request
To request a list of flavors:
response = service.list_flavors
This returns in the following `Excon::Response`:
<Excon::Response:0x007fe4b2ea2f38 @body={"flavors"=>[{"id"=>"2", "links"=>[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/flavors/2", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/flavors/2", "rel"=>"bookmark"}], "name"=>"512MB Standard Instance"}, {"id"=>"3", "links"=>[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/flavors/3", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/flavors/3", "rel"=>"bookmark"}], "name"=>"1GB Standard Instance"}, {"id"=>"4", "links"=>[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/flavors/4", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/flavors/4", "rel"=>"bookmark"}], "name"=>"2GB Standard Instance"}, {"id"=>"5", "links"=>[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/flavors/5", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/flavors/5", "rel"=>"bookmark"}], "name"=>"4GB Standard Instance"}, {"id"=>"6", "links"=>[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/flavors/6", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/flavors/6", "rel"=>"bookmark"}], "name"=>"8GB Standard Instance"}, {"id"=>"7", "links"=>[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/flavors/7", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/flavors/7", "rel"=>"bookmark"}], "name"=>"15GB Standard Instance"}, {"id"=>"8", "links"=>[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/flavors/8", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/flavors/8", "rel"=>"bookmark"}], "name"=>"30GB Standard Instance"}]}, @headers={"Date"=>"Mon, 21 Jan 2013 16:14:45 GMT", "Content-Length"=>"1697", "Content-Type"=>"application/json", "X-Compute-Request-Id"=>"req-0a1e8532-19b3-4993-8b48-cf2d9efe078c", "Server"=>"Jetty(8.0.y.z-SNAPSHOT)"}, @status=200>
To view the status of the response:
response.status
**Note**: Fog is aware of valid HTTP response statuses for each request type. If an unexpected HTTP response status occurs, Fog will raise an exception.
To view response body:
response.body
This will return:
{"flavors"=>[{"id"=>"2", "links"=>[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/flavors/2", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/flavors/2", "rel"=>"bookmark"}], "name"=>"512MB Standard Instance"}, {"id"=>"3", "links"=>[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/flavors/3", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/flavors/3", "rel"=>"bookmark"}], "name"=>"1GB Standard Instance"}, {"id"=>"4", "links"=>[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/flavors/4", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/flavors/4", "rel"=>"bookmark"}], "name"=>"2GB Standard Instance"}, {"id"=>"5", "links"=>[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/flavors/5", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/flavors/5", "rel"=>"bookmark"}], "name"=>"4GB Standard Instance"}, {"id"=>"6", "links"=>[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/flavors/6", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/flavors/6", "rel"=>"bookmark"}], "name"=>"8GB Standard Instance"}, {"id"=>"7", "links"=>[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/flavors/7", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/flavors/7", "rel"=>"bookmark"}], "name"=>"15GB Standard Instance"}, {"id"=>"8", "links"=>[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/flavors/8", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/flavors/8", "rel"=>"bookmark"}], "name"=>"30GB Standard Instance"}]}
To learn more about Compute request methods refer to [rdoc](http://rubydoc.info/gems/fog/Fog/Compute/Rackspace/Real). To learn more about Excon refer to [Excon GitHub repo](https://github.com/geemus/excon).
### Model Layer
Fog models behave in a manner similar to `ActiveModel`. Models will generally respond to `create`, `save`, `persisted?`, `destroy`, `reload` and `attributes` methods. Additionally, fog will automatically create attribute accessors.
Here is a summary of common model methods:
<table>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
<tr>
<td>create</td>
<td>
Accepts hash of attributes and creates object.<br>
Note: creation is a non-blocking call and you will be required to wait for a valid state before using resulting object.
</td>
</tr>
<tr>
<td>save</td>
<td>Saves object.<br>
Note: not all objects support updating object.</td>
</tr>
<tr>
<td>persisted?</td>
<td>Returns true if the object has been persisted.</td>
</tr>
<tr>
<td>destroy</td>
<td>
Destroys object.<br>
Note: this is a non-blocking call and object deletion might not be instantaneous.
</td>
<tr>
<td>reload</td>
<td>Updates object with latest state from service.</td>
<tr>
<td>ready?</td>
<td>Returns true if object is in a ready state and able to perform actions. This method will raise an exception if object is in an error state.</td>
</tr>
<tr>
<td>attributes</td>
<td>Returns a hash containing the list of model attributes and values.</td>
</tr>
<td>identity</td>
<td>
Returns the identity of the object.<br>
Note: This might not always be equal to object.id.
</td>
</tr>
<tr>
<td>wait_for</td>
<td>This method periodically reloads model and then yields to specified block until block returns true or a timeout occurs.</td>
</tr>
</table>
The remainder of this document details the model abstraction.
## List Images
To retrieve a list of available images:
service.images
This returns a collection of `Fog::Compute::RackspaceV2::Image` models:
<Fog::Compute::RackspaceV2::Images
[
<Fog::Compute::RackspaceV2::Image
id="8a3a9f96-b997-46fd-b7a8-a9e740796ffd",
name="Ubuntu 12.10 (Quantal Quetzal)",
created=nil,
updated=nil,
state=nil,
user_id=nil,
tenant_id=nil,
progress=nil,
minDisk=nil,
minRam=nil,
metadata=nil,
disk_config=nil,
links=[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/images/8a3a9f96-b997-46fd-b7a8-a9e740796ffd", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/images/8a3a9f96-b997-46fd-b7a8-a9e740796ffd", "rel"=>"bookmark"}, {"href"=>"https://ord.images.api.rackspacecloud.com/772045/images/8a3a9f96-b997-46fd-b7a8-a9e740796ffd", "type"=>"application/vnd.openstack.image", "rel"=>"alternate"}]
>,
<Fog::Compute::RackspaceV2::Image
id="992ba82c-083b-4eed-9c26-c54473686466",
name="Windows Server 2012 + SharePoint Foundation 2013 with SQL Server 2012 Standard",
created=nil,
updated=nil,
state=nil,
user_id=nil,
tenant_id=nil,
progress=nil,
minDisk=nil,
minRam=nil,
metadata=nil,
disk_config=nil,
links=[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/images/992ba82c-083b-4eed-9c26-c54473686466", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/images/992ba82c-083b-4eed-9c26-c54473686466", "rel"=>"bookmark"}, {"href"=>"https://ord.images.api.rackspacecloud.com/772045/images/992ba82c-083b-4eed-9c26-c54473686466", "type"=>"application/vnd.openstack.image", "rel"=>"alternate"}]
>,
## Get Image
To retrieve individual image:
service.images.get "8a3a9f96-b997-46fd-b7a8-a9e740796ffd"
This returns an `Fog::Compute::RackspaceV2::Image` instance:
<Fog::Compute::RackspaceV2::Image
id="8a3a9f96-b997-46fd-b7a8-a9e740796ffd",
name="Ubuntu 12.10 (Quantal Quetzal)",
created="2012-11-27T15:27:08Z",
updated="2012-11-28T14:35:21Z",
state="ACTIVE",
user_id=nil,
tenant_id=nil,
progress=100,
minDisk=10,
minRam=512,
metadata={"os_distro"=>"ubuntu", "com.rackspace__1__visible_core"=>"1", "com.rackspace__1__build_rackconnect"=>"1", "auto_disk_config"=>"True", "com.rackspace__1__options"=>"0", "image_type"=>"base", "org.openstack__1__os_version"=>"12.10", "os_version"=>"12.10", "rax_options"=>"0", "com.rackspace__1__visible_rackconnect"=>"1", "org.openstack__1__os_distro"=>"org.ubuntu", "com.rackspace__1__visible_managed"=>"1", "com.rackspace__1__build_core"=>"1", "arch"=>"x86-64", "os_type"=>"linux", "org.openstack__1__architecture"=>"x64", "com.rackspace__1__build_managed"=>"1"},
disk_config="AUTO",
links=[{"href"=>"https://ord.servers.api.rackspacecloud.com/v2/772045/images/8a3a9f96-b997-46fd-b7a8-a9e740796ffd", "rel"=>"self"}, {"href"=>"https://ord.servers.api.rackspacecloud.com/772045/images/8a3a9f96-b997-46fd-b7a8-a9e740796ffd", "rel"=>"bookmark"}, {"href"=>"https://ord.images.api.rackspacecloud.com/772045/images/8a3a9f96-b997-46fd-b7a8-a9e740796ffd", "type"=>"application/vnd.openstack.image", "rel"=>"alternate"}]
>
## List Flavors
To retrieve a list of available flavors:
service.flavors
This returns a collection of `Fog::Compute::RackspaceV2::Flavor` models:
<Fog::Compute::RackspaceV2::Flavors
[
<Fog::Compute::RackspaceV2::Flavor
id="2",
name="512MB Standard Instance",
ram=nil,
disk=nil,
vcpus=nil,
links=[{"href"=>"https://dfw.servers.api.rackspacecloud.com/v2/772045/flavors/2", "rel"=>"self"}, {"href"=>"https://dfw.servers.api.rackspacecloud.com/772045/flavors/2", "rel"=>"bookmark"}]
>,
<Fog::Compute::RackspaceV2::Flavor
id="3",
name="1GB Standard Instance",
ram=nil,
disk=nil,
vcpus=nil,
links=[{"href"=>"https://dfw.servers.api.rackspacecloud.com/v2/772045/flavors/3", "rel"=>"self"}, {"href"=>"https://dfw.servers.api.rackspacecloud.com/772045/flavors/3", "rel"=>"bookmark"}]
>,
## Get Flavor
To retrieve individual flavor:
service.flavor.get 2
This returns a `Fog::Compute::RackspaceV2::Flavor` instance:
<Fog::Compute::RackspaceV2::Flavor
id="2",
name="512MB Standard Instance",
ram=512,
disk=20,
vcpus=1,
links=[{"href"=>"https://dfw.servers.api.rackspacecloud.com/v2/772045/flavors/2", "rel"=>"self"}, {"href"=>"https://dfw.servers.api.rackspacecloud.com/772045/flavors/2", "rel"=>"bookmark"}]
>
## List Servers
To retrieve a list of available servers:
service.servers
This returns a collection of `Fog::Compute::RackspaceV2::Servers` models:
<Fog::Compute::RackspaceV2::Servers
[
<Fog::Compute::RackspaceV2::Server
id="6a273531-8ee4-4bef-ad1a-baca963f8bbb",
name="rax-example",
created="2013-01-17T22:28:14Z",
updated="2013-01-17T22:31:19Z",
host_id="7361c18d94a9933039dae57ae07b0a39fdb39ea3775a25329086531f",
state="ACTIVE",
progress=100,
user_id="296063",
tenant_id="772045",
links=[{"href"=>"https://dfw.servers.api.rackspacecloud.com/v2/772045/servers/6a273531-8ee4-4bef-ad1a-baca963f8bbb", "rel"=>"self"}, {"href"=>"https://dfw.servers.api.rackspacecloud.com/772045/servers/6a273531-8ee4-4bef-ad1a-baca963f8bbb", "rel"=>"bookmark"}],
metadata={},
personality=nil,
ipv4_address="198.101.255.186",
ipv6_address="2001:4800:780e:0510:0fe1:75e8:ff04:c4a0",
disk_config="AUTO",
bandwidth=[],
addresses={"public"=>[{"version"=>4, "addr"=>"198.101.255.186"}, {"version"=>6, "addr"=>"2001:4800:780e:0510:0fe1:75e8:ff04:c4a0"}], "private"=>[{"version"=>4, "addr"=>"10.180.22.165"}]},
flavor_id="2",
image_id="33e21646-43ed-407e-9dbf-7c7873fccd9a"
>,
## Get Server
To return an individual server:
service.servers.get "6a273531-8ee4-4bef-ad1a-baca963f8bbb"
This returns a `Fog::Compute::RackspaceV2::Server` instance:
<Fog::Compute::RackspaceV2::Servers
[
<Fog::Compute::RackspaceV2::Server
id="6a273531-8ee4-4bef-ad1a-baca963f8bbb",
name="rax-example",
created="2013-01-17T22:28:14Z",
updated="2013-01-17T22:31:19Z",
host_id="7361c18d94a9933039dae57ae07b0a39fdb39ea3775a25329086531f",
state="ACTIVE",
progress=100,
user_id="296063",
tenant_id="772045",
links=[{"href"=>"https://dfw.servers.api.rackspacecloud.com/v2/772045/servers/6a273531-8ee4-4bef-ad1a-baca963f8bbb", "rel"=>"self"}, {"href"=>"https://dfw.servers.api.rackspacecloud.com/772045/servers/6a273531-8ee4-4bef-ad1a-baca963f8bbb", "rel"=>"bookmark"}],
metadata={},
personality=nil,
ipv4_address="198.101.255.186",
ipv6_address="2001:4800:780e:0510:0fe1:75e8:ff04:c4a0",
disk_config="AUTO",
bandwidth=[],
addresses={"public"=>[{"version"=>4, "addr"=>"198.101.255.186"}, {"version"=>6, "addr"=>"2001:4800:780e:0510:0fe1:75e8:ff04:c4a0"}], "private"=>[{"version"=>4, "addr"=>"10.180.22.165"}]},
flavor_id="2",
image_id="33e21646-43ed-407e-9dbf-7c7873fccd9a"
>,
...
## Create Server
If you are interested in creating a server utilizing ssh key authenication, you are recommended to use [bootstrap](#bootstrap) method.
To create a server:
flavor = service.flavors.first
image = service.images.first
server = service.servers.create(:name => 'fog-doc', :flavor_id => flavor.id, :image_id => image.id)
**Note**: The `:name`, `:flavor_id`, and `image_id` attributes are required for server creation.
This will return a `Fog::Compute::RackspaceV2::Server` instance:
<Fog::Compute::RackspaceV2::Server
id="8ff308a6-e04a-4602-b991-ed526ab3b6be",
name="fog-server",
created=nil,
updated=nil,
host_id=nil,
state=nil,
progress=nil,
user_id=nil,
tenant_id=nil,
links=[{"href"=>"https://dfw.servers.api.rackspacecloud.com/v2/772045/servers/8ff308a6-e04a-4602-b991-ed526ab3b6be", "rel"=>"self"}, {"href"=>"https://dfw.servers.api.rackspacecloud.com/772045/servers/8ff308a6-e04a-4602-b991-ed526ab3b6be", "rel"=>"bookmark"}],
metadata=nil,
personality=nil,
ipv4_address=nil,
ipv6_address=nil,
disk_config="AUTO",
bandwidth=nil,
addresses=nil,
flavor_id=2,
image_id="3afe97b2-26dc-49c5-a2cc-a2fc8d80c001"
>
Notice that your server contains several `nil` attributes. To see the latest status, reload the instance as follows:
server.reload
You can see that the server is currently 17% built:
Fog::Compute::RackspaceV2::Server
id="8ff308a6-e04a-4602-b991-ed526ab3b6be",
name="fog-server",
created="2013-01-18T16:15:41Z",
updated="2013-01-18T16:16:14Z",
host_id="775837108e45aa3f2a58527c9c3b6160838078e83148f07906c933ca",
state="BUILD",
progress=17,
user_id="296063",
tenant_id="772045",
links=[{"href"=>"https://dfw.servers.api.rackspacecloud.com/v2/772045/servers/8ff308a6-e04a-4602-b991-ed526ab3b6be", "rel"=>"self"}, {"href"=>"https://dfw.servers.api.rackspacecloud.com/772045/servers/8ff308a6-e04a-4602-b991-ed526ab3b6be", "rel"=>"bookmark"}],
metadata={},
personality=nil,
ipv4_address="",
ipv6_address="",
disk_config="AUTO",
bandwidth=[],
addresses={"public"=>[{"version"=>4, "addr"=>"198.61.209.78"}, {"version"=>6, "addr"=>"2001:4800:7810:0512:0fe1:75e8:ff04:94e4"}], "private"=>[{"version"=>4, "addr"=>"10.181.13.198"}]},
flavor_id="2",
image_id="3afe97b2-26dc-49c5-a2cc-a2fc8d80c001"
>
You will be unable to perform any actions to this server until it reaches an `ACTIVE` state. Since this is true for most server actions, Fog provides the convenience method `wait_for`.
Fog can wait for the server to become ready as follows:
server.wait_for { ready? }
**Note**: The `Fog::Compute::RackspaceV2::Server` instance returned from the create method contains a `password` attribute. The `password` attribute will NOT be present in subsequent retrievals either through `service.servers` or `server.servers.get my_server_id`.
### Additional Parameters
The `create` method also supports the following key values:
<table>
<tr>
<th>Key</th>
<th>Description</th>
</tr>
<tr>
<td>:disk_config</td>
<td>The disk configuration value (AUTO or MANUAL). Refer to Next Gen Server API documentation - <a href="http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ch_extensions.html#diskconfig_attribute">Disk Configuration Extension</a>.</td>
</tr>
<tr>
<td>:metadata</td>
<td>Hash containing server metadata.</td>
</tr>
<tr>
<td>:personality</td>
<td>Array of files to be injected onto the server. Please refer to the Fog <a href="http://rubydoc.info/github/fog/fog/Fog/Compute/RackspaceV2/Server:personality">personality </a> API documentation for further information.</td>
</tr>
<tr>
<td>:config_drive</td>
<td>Whether a read-only configuration drive is attached. Refer to Next Gen Server API documentation - <a
href="http://docs.rackspace.com/servers/api/v2/cs-devguide/content/config_drive_ext.html">Config Drive Extension</a>.</td>
</tr>
</table>
## Bootstrap
In addition to the `create` method, Fog provides a `bootstrap` method which creates a server and then performs the following actions via ssh:
1. Create `ROOT_USER/.ssh/authorized_keys` file using the ssh key specified in `:public_key_path`.
2. Lock password for root user using `passwd -l root`.
3. Create `ROOT_USER/attributes.json` file with the contents of `server.attributes`.
4. Create `ROOT_USER/metadata.json` file with the contents of `server.metadata`.
**Note**: Unlike the `create` method, `bootstrap` is blocking method call. If non-blocking behavior is desired, developers should use the `:personality` parameter on the `create` method.
The following example demonstrates bootstraping a server:
service.servers.bootstrap :name => 'bootstrap-server',
:flavor_id => service.flavors.first.id,
:image_id => service.images.find {|img| img.name =~ /Ubuntu/}.id,
:public_key_path => '~/.ssh/fog_rsa.pub',
:private_key_path => '~/.ssh/fog_rsa'
**Note**: The `:name`, `:flavor_id`, `:image_id`, `:public_key_path`, `:private_key_path` are required for the `bootstrap` method.
The `bootstrap` method uses the same additional parameters as the `create` method. Refer to the [Additional Parameters](#additional-parameters) section for more information.
## SSH
Once a server has been created and set up for ssh key authentication, fog can execute remote commands as follows:
result = server.ssh ['pwd']
This will return the following:
[#<Fog::SSH::Result:0x1108241d0 @stderr="", @status=0, @stdout="/root\r\n", @command="pwd">]
**Note**: SSH key authentication can be set up using `bootstrap` method or by using the `:personality` attribute on the `:create` method. See [Bootstrap](#bootstrap) or [Create Server](#create-server) for more information.
## Update Server
Next Gen Cloud Servers support updating the following attributes `name`, `access_ipv4_address`, and `access_ipv6_address`.
To update these attributes:
server.name = "batman"
server.access_ipv4_address = "10.0.0.1"
server.access_ipv6_address = "fdbb:1717:4533:7c89:0:0:0:1"
server.save
Additional information about server access addresses can be found [here](http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Server_Primary_Addresses-d1e2558.html).
**Note**: Updating the server name does not change the host name. Names are not guaranteed to be unique.
## Delete Server
To delete a server:
server.destroy
**Note**: The server is not immediately destroyed, but it does occur shortly there after.
## Metadata
You can access metadata as an attribute on both `Fog::Compute::RackspaceV2::Server` and `Fog::Compute::RackspaceV2::Metadata::Image`. You can specify metadata during creation of a server or an image. Please refer to [Create Server](#create-server) or [Create Image](#create-image) sections for more information.
This example demonstrates how to iterate through a server's metadata:
server.metadata.each {|metadatum| puts "#{metadatum.key}: #{metadatum.value}" }
You can update and retrieve metadata in a manner similar to a hash:
server.metadata["os_type"]
server.metadata["installed_ruby"] = "MRI 1.9.3"
Metadata also responds to `save` and `reload` as follows:
server.metadata.save
server.metadata.reload
## Change Admin Password
To change the administrator password:
server.change_admin_password "superSecure"
## Reboot
To perform a soft reboot:
server.reboot
To perform a hard reboot:
server.reboot 'HARD'
## Rebuild
Rebuild removes all data on the server and replaces it with the specified image. The id and all IP addresses remain the same.
To rebuild a server:
image = service.images.first
server.rebuild image.id
Additionally, the `rebuild` method will take a second parameter containing a hash with the following values:
<table>
<tr>
<th>Key</th>
<th>Description</th>
</tr>
<tr>
<td>:name</td>
<td>Name of Server</td>
</tr>
<tr>
<td>:flavorRef</td>
<td>Flavor id</td>
</tr>
<tr>
<td>:accessIPv4</td>
<td>IPv4 access address</td>
</tr>
<tr>
<td>:accessIPv6</td>
<td>IPv6 access address</td>
</tr>
<tr>
<td>:metadata</td>
<td>Hash containing server metadata</td>
</tr>
<tr>
<td>:personality</td>
<td>File path and contents. Refer to Next Gen Server API documentation - <a href="http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Server_Personality-d1e2543.html">Server Personality</a>. </td>
</tr>
<tr>
<td>:disk_config</td>
<td>The disk configuration value (AUTO or MANUAL). Refer to Next Gen Server API documentation - <a href="http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ch_extensions.html#diskconfig_attribute">Disk Configuration Extension</a>.</td>
</tr>
</table>
## Resize
Resizing a server allows you to change the resources dedicated to the server.
To resize a server:
flavor_id = service.flavor[2].id
server.resize flavor_id #flavor_id should be your desired flavor
During the resize process the server will have a state of `RESIZE`. Once a server has completed resizing it will be in a `VERIFY_RESIZE` state.
You can use Fog's `wait_for` method to wait for this state as follows:
server.wait_for { ready?('VERIFY_RESIZE', ['ACTIVE', 'ERROR']) }
In this case, `wait_for` is waiting for the server to become `VERIFY_READY` and will raise an exception if we enter an `ACTIVE` or `ERROR` state.
Once a server enters the `VERIFY_RESIZE` we will need to call `confirm_resize` to confirm the server was properly resized or `revert_resize` to rollback to the old size/flavor.
**Note:** A server will automatically confirm resize after 24 hours.
To confirm resize:
server.confirm_resize
To revert to previous size/flavor:
server.revert_resize
## Create Image
To create an image of your server:
image = server.create_image "back-image-#{server.name}", :metadata => { :environment => 'development' }
You can use the second parameter to specify image metadata. This is an optional parameter.
During the imaging process, the image state will be `SAVING`. The image is ready for use when when state `ACTIVE` is reached. Fog can use `wait_for` to wait for an active state as follows:
image.wait_for { ready? }
## List Attached Volumes
To list Cloud Block Volumes attached to server:
server.attachments
## Attach Volume
To attach volume using the volume id:
server.attach_volume "0e7a706c-340d-48b3-802d-192850387f93"
If the volume id is unknown you can look it up using the Cloud Block Storage service. Start by creating a `cbs_service` similar to our Compute Service:
cbs_service = Fog::Rackspace::BlockStorage.new({
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API # Your Rackspace API key
})
volume = cbs_service.volumes.first
server.attach_volume volume, "/dev/xvdb" # name of device on server is optional
The `attach_volume` method accepts a volume id `String` or `Fog::Rackspace::BlockStorage::Volume` instance. This example also demonstrates passing in the optional device name. Valid device names are `/dev/xvd[a-p]`.
## Detach Volume
To detach a volume:
server.attachments.first.detach
## Examples
Example code using Next Gen Cloud Servers can be found [here](https://github.com/fog/fog/tree/master/lib/fog/rackspace/examples).
## Additional Resources
* [fog.io](http://fog.io/)
* [Fog rdoc](http://rubydoc.info/gems/fog/)
* [Fog Github repo](https://github.com/fog/fog)
* [Fog Github Issues](https://github.com/fog/fog/issues)
* [Excon Github repo](https://github.com/geemus/excon)
* [Next Gen Cloud Servers API](http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ch_preface.html)
## Support and Feedback
Your feedback is appreciated! If you have specific issues with the **fog** SDK, you should file an [issue via Github](https://github.com/fog/fog/issues).
For general feedback and support requests, send an email to: <sdk-support@rackspace.com>.

Просмотреть файл

@ -0,0 +1,88 @@
# Getting Started with Fog and the Rackspace Cloud
This document explains how to get started using Fog with the [Rackspace Cloud](http://www.rackspace.com/cloud/).
## Requirements
### Ruby
Fog officially supports Ruby 2.1.1, 2.1.0, 2.0.0, 1.9.3, 1.9.2, and 1.8.7 (also known as Matz Ruby Interpreter or MRI). While not officially supported, fog has been known to work with Rubinus and JRuby.
Ruby 1.9.3 is suggested for new projects. For information on installing Ruby please refer to the [Ruby download page](http://www.ruby-lang.org/en/downloads/).
### RubyGems
RubyGems is required to access the Fog gem. For information on installing RubyGems, please refer to [RubyGems download page](http://rubygems.org/pages/download).
### Bundler (optional)
Bundler helps manage gem dependencies and is recommended for new projects. For more information about bundler, please refer to the [bundler documentation](http://gembundler.com/).
## Credentials
To obtain credentials for the US Rackspace Cloud, please sign up for an account at [US Rackspace Open Cloud](https://cart.rackspace.com/cloud/). Once an account is created, you can login to the [Cloud Control Panel (US)](https://mycloud.rackspace.com/), find your credentials by clicking on your username in the top right corner, and then select API keys.
Likewise, you can create an account on our UK Rackspace Open Cloud by signing up at [UK Rackspace Open Cloud](https://buyonline.rackspace.co.uk/cloud/userinfo?type=normal) and then logging into [Cloud Control Panel (UK)](https://mycloud.rackspace.co.uk/).
You will use the credentials when you explore fog services in the [Next Steps](#next-steps) section.
## Installation
To install Fog via RubyGems run the following command:
$ gem install fog
To install Fog via Bundler add `gem 'fog'` to your `Gemfile`. This is a sample `Gemfile` to install Fog:
source 'https://rubygems.org'
gem 'fog'
After creating your `Gemfile` execute the following command to install the libraries:
bundle install
## Next Steps
Now that you have installed Fog and obtained your credentials, you are ready to begin exploring the capabilities of the Rackspace Open Cloud and Fog using `irb`.
Start by executing the following command:
irb
Once `irb` has launched you will need to require the Fog library.
If using Ruby 1.8.x execute the following command:
require 'rubygems'
require 'fog'
If using Ruby 1.9.x execute the following command:
require 'fog'
You should now be able to execute the following command to see a list of services Fog provides for the Rackspace Open Cloud:
Fog::Rackspace.services
These services can be explored in further depth in the following documents:
* [Next Generation Cloud Servers™ (compute_v2)](compute_v2.md)
* [Cloud Files™ (storage)](storage.md)
* [Cloud Block Storage (block_storage)](block_storage.md)
* [Auto Scale (auto_scale)](auto_scale.md)
* [Queues](queues.md)
**Note**: The compute service provides an interface to the First Geneneration Cloud Servers™ (compute). This service is deprecated. Users are encouraged to use Next Geneneration Cloud Servers™ (compute_v2).
## Additional Resources
* [fog.io](http://fog.io)
* [Fog rdoc](http://rubydoc.info/gems/fog)
* [Fog Github repo](https://github.com/fog/fog)
* [Release Notes](https://github.com/fog/fog/blob/master/changelog.txt)
* [developer.rackspace.com](http://developer.rackspace.com/)
## Support and Feedback
Your feedback is appreciated! If you have specific issues with the **fog** SDK, you should file an [issue via Github](https://github.com/fog/fog/issues).
For general feedback and support requests, send an email to: <sdk-support@rackspace.com>.

Просмотреть файл

@ -0,0 +1,315 @@
#Networking (neutron)
This document explains how to get started using Networking with Fog. It assumes you have read the [Getting Started with Fog and the Rackspace Open Cloud](getting_started.md) document.
## Starting irb console
Start by executing the following command:
irb
Once `irb` has launched you need to require the Fog library.
If using Ruby 1.8.x execute:
require 'rubygems'
require 'fog'
If using Ruby 1.9.x execute:
require 'fog'
## Create Service
Next, create a connection to Rackspace's Networking API:
Using a US-based account:
service = Fog::Rackspace::Networking.new({
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:rackspace_region => :ord, # Defaults to :dfw
})
Using a UK-based account:
service = Fog::Compute.new({
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT,
:rackspace_region => :lon,
})
To learn more about obtaining cloud credentials refer to the [Getting Started with Fog and the Rackspace Open Cloud](getting_started.md) document.
By default `Fog::Rackspace::Networking` will authenticate against the US authentication endpoint and connect to the DFW region. You can specify alternative authentication endpoints using the key `:rackspace_auth_url`. Please refer to [Alternate Authentication Endpoints](http://docs.rackspace.com/auth/api/v2.0/auth-client-devguide/content/Endpoints-d1e180.html) for a list of alternative Rackspace authentication endpoints.
Alternative regions are specified using the key `:rackspace_region `. A list of regions available for Cloud Servers can be found by executing the following:
identity_service = Fog::Identity({
:provider => 'Rackspace', # Rackspace Fog provider
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT # Not specified for US Cloud
})
identity_service.service_catalog.display_service_regions :cloudServersOpenStack
### Optional Connection Parameters
Fog supports passing additional connection parameters to its underlying HTTP library (Excon) using the `:connection_options` parameter.
<table>
<tr>
<th>Key</th>
<th>Description</th>
</tr>
<tr>
<td>:connect_timeout</td>
<td>Connection timeout (default: 60 seconds)</td>
</tr>
<tr>
<td>:read_timeout</td>
<td>Read timeout for connection (default: 60 seconds)</td> </tr>
<tr>
<td>:write_timeout</td>
<td>Write timeout for connection (default: 60 seconds)</td>
</tr>
<tr>
<td>:proxy</td>
<td>Proxy for HTTP and HTTPS connections</td>
</tr>
<tr>
<td>:ssl_ca_path</td>
<td>Path to SSL certificate authorities</td>
</tr>
<tr>
<td>:ssl_ca_file</td>
<td>SSL certificate authority file</td>
</tr>
<tr>
<td>:ssl_verify_peer</td>
<td>SSL verify peer (default: true)</td>
</tr>
</table>
## Fog Abstractions
Fog provides both a **model** and **request** abstraction. The request abstraction provides the most efficient interface and the model abstraction wraps the request abstraction to provide a convenient `ActiveModel` like interface.
### Request Layer
The request abstraction maps directly to the [Networking API](http://docs.rackspace.com/networks/api/v2/cn-gettingstarted/content/ch_overview.html). It provides the most efficient interface to the Rackspace Networking
To see a list of requests supported by the service:
service.requests
This returns:
[:list_networks, :get_network, :create_network, :delete_network, :list_virtual_interfaces, :create_virtual_interface, :delete_virtual_interface]
#### Example Request
To request a list of flavors:
response = service.list_networks
This returns in the following `Excon::Response`:
<Excon::Response:0x0000010231acd8 @data={:body=>{"networks"=>[{"cidr"=>"192.168.0.0/24", "id"=>"08df79ae-b714-425c-ba25-91b0a8a78b9e", "label"=>"something"}, {"cidr"=>"192.168.0.0/24", "id"=>"eb3ed4b8-21d4-478e-9ae4-a35c0cc0437c", "label"=>"something"}, {"id"=>"00000000-0000-0000-0000-000000000000", "label"=>"public"}, {"id"=>"11111111-1111-1111-1111-111111111111", "label"=>"private"}]}, :headers=>{"Content-Type"=>"application/json", "Via"=>"1.1 Repose (Repose/2.12)", "Content-Length"=>"341", "Date"=>"Thu, 23 Oct 2014 20:53:41 GMT", "x-compute-request-id"=>"req-d34ab53c-45ed-433f-8a9d-b3341896b7e5", "Server"=>"Jetty(8.0.y.z-SNAPSHOT)"}, :status=>200, :remote_ip=>"162.209.116.128", :local_port=>60153, :local_address=>"192.168.1.65"}, @body="{\"networks\": [{\"cidr\": \"192.168.0.0/24\", \"id\": \"08df79ae-b714-425c-ba25-91b0a8a78b9e\", \"label\": \"something\"}, {\"cidr\": \"192.168.0.0/24\", \"id\": \"eb3ed4b8-21d4-478e-9ae4-a35c0cc0437c\", \"label\": \"something\"}, {\"id\": \"00000000-0000-0000-0000-000000000000\", \"label\": \"public\"}, {\"id\": \"11111111-1111-1111-1111-111111111111\", \"label\": \"private\"}]}", @headers={"Content-Type"=>"application/json", "Via"=>"1.1 Repose (Repose/2.12)", "Content-Length"=>"341", "Date"=>"Thu, 23 Oct 2014 20:53:41 GMT", "x-compute-request-id"=>"req-d34ab53c-45ed-433f-8a9d-b3341896b7e5", "Server"=>"Jetty(8.0.y.z-SNAPSHOT)"}, @status=200, @remote_ip="162.209.116.128", @local_port=60153, @local_address="192.168.1.65">
To view the status of the response:
response.status
**Note**: Fog is aware of valid HTTP response statuses for each request type. If an unexpected HTTP response status occurs, Fog will raise an exception.
To view response body:
response.body
This will return:
{"networks"=>[{"cidr"=>"192.168.0.0/24", "id"=>"08df79ae-b714-425c-ba25-91b0a8a78b9e", "label"=>"something"}, {"cidr"=>"192.168.0.0/24", "id"=>"eb3ed4b8-21d4-478e-9ae4-a35c0cc0437c", "label"=>"something"}, {"id"=>"00000000-0000-0000-0000-000000000000", "label"=>"public"}, {"id"=>"11111111-1111-1111-1111-111111111111", "label"=>"private"}]}
To learn more about Networking request methods refer to [rdoc](http://www.rubydoc.info/gems/fog/Fog/Rackspace/Networking/Real). To learn more about Excon refer to [Excon GitHub repo](https://github.com/geemus/excon).
### Model Layer
Fog models behave in a manner similar to `ActiveModel`. Models will generally respond to `create`, `save`, `persisted?`, `destroy`, `reload` and `attributes` methods. Additionally, fog will automatically create attribute accessors.
Here is a summary of common model methods:
<table>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
<tr>
<td>create</td>
<td>
Accepts hash of attributes and creates object.<br>
Note: creation is a non-blocking call and you will be required to wait for a valid state before using resulting object.
</td>
</tr>
<tr>
<td>save</td>
<td>Saves object.<br>
Note: not all objects support updating object.</td>
</tr>
<tr>
<td>persisted?</td>
<td>Returns true if the object has been persisted.</td>
</tr>
<tr>
<td>destroy</td>
<td>
Destroys object.<br>
Note: this is a non-blocking call and object deletion might not be instantaneous.
</td>
<tr>
<td>reload</td>
<td>Updates object with latest state from service.</td>
<tr>
<td>ready?</td>
<td>Returns true if object is in a ready state and able to perform actions. This method will raise an exception if object is in an error state.</td>
</tr>
<tr>
<td>attributes</td>
<td>Returns a hash containing the list of model attributes and values.</td>
</tr>
<td>identity</td>
<td>
Returns the identity of the object.<br>
Note: This might not always be equal to object.id.
</td>
</tr>
<tr>
<td>wait_for</td>
<td>This method periodically reloads model and then yields to specified block until block returns true or a timeout occurs.</td>
</tr>
</table>
The remainder of this document details the model abstraction.
## List Networks
To retrieve a list of available networks:
service.networks
This returns a collection of `Fog::Rackspace::Networking::Network` models:
<Fog::Rackspace::Networking::Networks
[
<Fog::Rackspace::Networking::Network
id="08df79ae-b714-425c-ba25-91b0a8a78b9e",
label="something",
cidr="192.168.0.0/24"
>,
<Fog::Rackspace::Networking::Network
id="eb3ed4b8-21d4-478e-9ae4-a35c0cc0437c",
label="something",
cidr="192.168.0.0/24"
>,
<Fog::Rackspace::Networking::Network
id="00000000-0000-0000-0000-000000000000",
label="public",
cidr=nil
>,
<Fog::Rackspace::Networking::Network
id="11111111-1111-1111-1111-111111111111",
label="private",
cidr=nil
>
]
>
## Create Network
Create a network:
service.networks.create(label: "new_network", cidr: "192.168.0.0/24")
## Get Network
To retrieve individual network:
service.networks.get "8a3a9f96-b997-46fd-b7a8-a9e740796ffd"
This returns an `Fog::Rackspace::Networking::Network` instance:
<Fog::Rackspace::Networking::Network
id="08df79ae-b714-425c-ba25-91b0a8a78b9e",
label="new_network",
cidr="192.168.0.0/24"
>
## Delete Network
To delete a network:
network.destroy
**Note**: The network is not immediately destroyed, but it does occur shortly there after.
## List Virtual Interfaces
To retrieve a list of available virtual interfaces:
service.virtual_interfaces.all(server: <server obj, or server id>)
This returns a collection of `Fog::Rackspace::Networking::VirtualInterface` models:
<Fog::Rackspace::Networking::VirtualInterfaces
[
<Fog::Rackspace::Networking::VirtualInterface
id="f063815f-e576-450e-92bd-ff3aeeeb11e0",
mac_address="BC:76:4E:20:A9:16",
ip_addresses=[{"network_id"=>"11111111-1111-1111-1111-111111111111", "network_label"=>"private", "address"=>"10.176.12.249"}]
>,
<Fog::Rackspace::Networking::VirtualInterface
id="f8196e20-788b-4447-80a5-32ca8fc9622f",
mac_address="BC:76:4E:20:A8:56",
ip_addresses=[{"network_id"=>"08df79ae-b714-425c-ba25-91b0a8a78b9e", "network_label"=>"new_network", "address"=>"192.168.0.1"}]
>
]
>
## Create Virtual Interface
Create a virtual interface:
service.virtual_interfaces.create(network: <network_id>, server: <server_id>)
## Delete Virtual Interface
To delete a virtual interface:
vis = service.virtual_interfaces.all(server: <server obj, or server id>)
vis.first.destroy
**Note**: The virtual interface is not immediately destroyed, but it does occur shortly there after.
## Examples
Example code using Networking can be found [here](https://github.com/fog/fog/tree/master/lib/fog/rackspace/examples).
## Additional Resources
* [fog.io](http://fog.io/)
* [Fog rdoc](http://rubydoc.info/gems/fog/)
* [Fog Github repo](https://github.com/fog/fog)
* [Fog Github Issues](https://github.com/fog/fog/issues)
* [Excon Github repo](https://github.com/geemus/excon)
* [Rackspace Networking API](http://docs.rackspace.com/networking/api/v2/cs-devguide/content/ch_preface.html)
## Support and Feedback
Your feedback is appreciated! If you have specific issues with the **fog** SDK, you should file an [issue via Github](https://github.com/fog/fog/issues).
For general feedback and support requests, send an email to: <sdk-support@rackspace.com>.

Просмотреть файл

@ -0,0 +1,312 @@
#Cloud Queues (queues)
This document explains how to get started using queues with Fog. It assumes you have read the [Getting Started with Fog and the Rackspace Open Cloud](getting_started.md) document.
## Basic Concepts
Cloud Queues is an open source, scalable, and highly available message and notifications service, based on the OpenStack Marconi project. Users of this service can create and manage a producer-consumer or a publisher-subscriber model. Unlimited queues and messages give users the flexibility they need to create powerful web applications in the cloud.
It consists of a few basic components: queues, messages, claims, and statistics. In the producer-consumer model, users create queues in which producers, or servers, can post messages. Workers, or consumers, can then claim those messages and delete them after they complete the actions associated with the messages. A single claim can contain multiple messages, and administrators can query claims for status.
In the publisher-subscriber model, messages are posted to a queue as in the producer-consumer model, but messages are never claimed. Instead, subscribers, or watchers, send GET requests to pull all messages that have been posted since their last request. In this model, a message remains in the queue, unclaimed, until the message's time to live (TTL) has expired.
In both of these models, administrators can get queue statistics that display the most recent and oldest messages, the number of unclaimed messages, and more.
## Starting irb console
Start by executing the following command:
irb
Once `irb` has launched you need to require the Fog library as follows:
require 'fog'
## Create Service
Next, create a connection to queue service:
Using a US-based account:
service = Fog::Rackspace::Queues(
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:rackspace_region => :ord, # Your desired region
:rackspace_queues_client_id => CLIENT_ID, # Your client ID
:connection_options => {} # Optional connection options
)
Using a UK-based account:
service = Fog::Rackspace::Queues(
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT,
:rackspace_region => :lon, # Your desired region
:rackspace_queues_client_id => CLIENT_ID', # Your client ID
:connection_options => {} # Optional connection options
)
To learn more about obtaining cloud credentials refer to the [Getting Started with Fog and the Rackspace Open Cloud](getting_started.md) document.
### Authentication Endpoint
By default `Fog::Rackspace::Queues` will authenticate against the US authentication endpoint. You can specify alternative authentication endpoints using the key `:rackspace_auth_url`. Please refer to [Alternate Authentication Endpoints](http://docs.rackspace.com/auth/api/v2.0/auth-client-devguide/content/Endpoints-d1e180.html) for a list of alternative Rackspace authentication endpoints.
### Regions
Alternative regions are specified using the key `:rackspace_region `. A list of regions available for cloud queues can be found by executing the following:
identity_service = Fog::Identity({
:provider => 'Rackspace', # Rackspace Fog provider
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT # Not specified for US Cloud
})
identity_service.service_catalog.display_service_regions :queues
### Private Cloud
Rackspace Private Cloud installations can skip specifying a region and directly specify their custom service endpoints using the key `:rackspace_queues_url`.
**Note**: A`Fog::Rackspace::Queues` instance is needed for the desired region.
### Client ID
The Rackspace Queue service requires that every client define a client id to help identify messages and claims specific to the client. This client id should take the form of a UUID and can be generated using fog as follows:
Fog::UUID.uuid
If the client id is omitted fog will generate one for you.
### Optional Connection Parameters
Fog supports passing additional connection parameters to its underlying HTTP library (Excon) using the `:connection_options` parameter.
<table>
<tr>
<th>Key</th>
<th>Description</th>
</tr>
<tr>
<td>:connect_timeout</td>
<td>Connection timeout (default: 60 seconds)</td>
</tr>
<tr>
<td>:read_timeout</td>
<td>Read timeout for connection (default: 60 seconds)</td> </tr>
<tr>
<td>:write_timeout</td>
<td>Write timeout for connection (default: 60 seconds)</td>
</tr>
<tr>
<td>:proxy</td>
<td>Proxy for HTTP and HTTPS connections</td>
</tr>
<tr>
<td>:ssl_ca_path</td>
<td>Path to SSL certificate authorities</td>
</tr>
<tr>
<td>:ssl_ca_file</td>
<td>SSL certificate authority file</td>
</tr>
<tr>
<td>:ssl_verify_peer</td>
<td>SSL verify peer (default: true)</td>
</tr>
</table>
## Fog Abstractions
Fog provides both a **model** and **request** abstraction. The request abstraction provides the most efficient interface and the model abstraction wraps the request abstraction to provide a convenient `ActiveModel`-like interface.
### Request Layer
The request abstraction maps directly to the [Queue API](http://docs.rackspace.com/queues/api/v1.0/cq-devguide/content/overview.html). It provides the most efficient interface to the Rackspace Open Cloud.
To see a list of requests supported by the service:
service.requests
This returns:
:list_queues, :get_queue, :create_queue, :delete_queue, :get_queue_stats, :list_messages, :get_message, :create_message, :delete_message, :create_claim, :get_claim, :update_claim, :delete_claim
#### Example Request
To request a list of queues:
response = service.list_queues
This returns in the following `Excon::Response`:
#<Excon::Response:0x007feddda06e00 @data={:body=>{"queues"=>[{"href"=>"/v1/queues/demo-queue", "name"=>"demo-queue"}], "links"=>[{"href"=>"/v1/queues?marker=demo-queue", "rel"=>"next"}]}, :headers=>{"Content-Length"=>"119", "Content-Type"=>"application/json; charset=utf-8", "Content-Location"=>"/v1/queues", "X-Project-ID"=>"5551212"}, :status=>200, :remote_ip=>"10.10.0.1"}, @body="{\"queues\": [{\"href\": \"/v1/queues/demo-queue\", \"name\": \"demo-queue\"}], \"links\": [{\"href\": \"/v1/queues?marker=demo-queue\", \"rel\": \"next\"}]}", @headers={"Content-Length"=>"119", "Content-Type"=>"application/json; charset=utf-8", "Content-Location"=>"/v1/queues", "X-Project-ID"=>"5551212"}, @status=200, @remote_ip="10.10.0.1">
To view the status of the response:
response.status
**Note**: Fog is aware of valid HTTP response statuses for each request type. If an unexpected HTTP response status occurs, Fog will raise an exception.
To view response body:
response.body
This returns:
{"queues"=>[{"href"=>"/v1/queues/demo-queue", "name"=>"demo-queue"}], "links"=>[{"href"=>"/v1/queues?marker=demo-queue", "rel"=>"next"}]}
To learn more about queue request methods refer to [rdoc](http://rubydoc.info/gems/fog/Fog/Rackspace/Queues/Real). To learn more about Excon refer to [Excon GitHub repo](https://github.com/geemus/excon).
### Model Layer
Fog models behave in a manner similar to `ActiveModel`. Models will generally respond to `create`, `save`, `persisted?`, `destroy`, `reload` and `attributes` methods. Additionally, fog will automatically create attribute accessors.
Here is a summary of common model methods:
<table>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
<tr>
<td>create</td>
<td>
Accepts hash of attributes and creates object.<br>
Note: creation is a non-blocking call and you will be required to wait for a valid state before using resulting object.
</td>
</tr>
<tr>
<td>save</td>
<td>Saves object.<br>
Note: not all objects support updating object.</td>
</tr>
<tr>
<td>persisted?</td>
<td>Returns true if the object has been persisted.</td>
</tr>
<tr>
<td>destroy</td>
<td>
Destroys object.<br>
Note: this is a non-blocking call and object deletion might not be instantaneous.
</td>
<tr>
<td>reload</td>
<td>Updates object with latest state from service.</td>
<tr>
<td>ready?</td>
<td>Returns true if object is in a ready state and able to perform actions. This method will raise an exception if object is in an error state.</td>
</tr>
<tr>
<td>attributes</td>
<td>Returns a hash containing the list of model attributes and values.</td>
</tr>
<td>identity</td>
<td>
Returns the identity of the object.<br>
Note: This might not always be equal to object.id.
</td>
</tr>
<tr>
<td>wait_for</td>
<td>This method periodically reloads model and then yields to specified block until block returns true or a timeout occurs.</td>
</tr>
</table>
The remainder of this document details the model abstraction.
## Create Queue
Queues require a unique name. If you try to create a queue with a name that already exists, fog will throw a `Fog::Rackspace::Queues::ServiceError` exception with a 204 status code.
To create a queue named demo-queue
begin
queue = service.queues.create :name => 'demo-queue'
rescue Fog::Rackspace::Queues::ServiceError => e
if e.status_code == 204
# duplicate queue exists
end
end
## Posting a Message to a Queue
Messages can be any type of data, as long as they do not exceed 256 KB in length. Typical message bodies range from simple values, to a chunk of XML, or a list of JSON values. Fog handles the JSON-encoding required to post the message.
You can post a message a message to your queue as follows:
queue.messages.create :body => 'The laces were out!', :ttl => 360
You must supply both a body and a value for `ttl`. The value of `ttl` must be between 60 and 1209600 seconds (one minute to 14 days).
## Listing Messages in a Queue
To list messages:
queue.messages
You can change the behavior by setting the follow attributes on the messages collection:
Parameter | Default | Effect
---- | ---- | ----
**echo** | `true` | When `true`, your own messages are included.
**include_claimed** | `false` | By default, only unclaimed messages are returned. Pass this as `true` to get all messages, claimed or not.
**marker** | `nil` | Used for pagination.
**limit** | `10` | The maximum number of messages to return. Note that you may receive fewer than the specified limit if there aren't that many available messages in the queue.
For example, to include claimed messages:
queue.messages.include_claimed = true
queue.messages
## Claiming Messages in a Queue
Claiming messages is how workers processing a queue mark messages as being handled by that worker, avoiding having two workers process the same message.
Messages can be claimed and processed as follows:
claims = queue.claims.create :ttl => 300, :grace => 100, :limit => 10
The parameters for this call are described in the following table:
Parameter | Default | Notes
---- | ---- | ----
**ttl** | | The ttl attribute specifies how long the server waits before releasing the claim. The ttl value must be between 60 and 43200 seconds (12 hours).
**grace** | | The grace attribute specifies the message grace period in seconds. The value of the grace period must be between 60 and 43200 seconds (12 hours). To deal with workers that have stopped responding (for up to 1209600 seconds or 14 days, including claim lifetime), the server extends the lifetime of claimed messages to be at least as long as the lifetime of the claim itself, plus the specified grace period. If a claimed message would normally live longer than the grace period, its expiration is not adjusted.
**limit** | 10 | The number of messages to claim. The maximum number of messages you may claim at once is 20.
If the claim is successful it will return a `Fog::Rackspace::Queues::Claims` object; if there are not any available messages it will return `false`.
To iterate through the claimed messages:
claim.messages.each do |message|
# process message here
message.destroy
end
**Note:** You will want to call the `destroy` method on the message after processing to insure it is not processed more than once.
## Renewing a Claim
Once a claim has been made, if the TTL and grace period expire, the claim is automatically released and the messages are made available for others to claim. If you have a long-running process and want to ensure that this does not happen in the middle of the process, you should update the claim with one or both of a TTL or grace period. Updating resets the age of the claim, restarting the TTL for the claim. To update a claim, call:
claim.ttl = 360
claim.grace = 360
claim.save
## Refreshing a Claim
If you have a `Fog::Rackspace::Queues::claims` object, keep in mind that it is not a live window into the status of the claim; rather, it is a snapshot of the claim at the time the object was created. To refresh it with the latest information, call its `reload` method. This refreshes all of its attributes with the most current status of the claim.
## Releasing a Claim
If you have a claim on several messages and must abandon processing of those messages for any reason, you should release the claim so that those messages can be processed by other workers as soon as possible, instead of waiting for the claim's TTL to expire. When you release a claim, the claimed messages are immediately made available in the queue for other workers to claim. To release a claim, call:
claim.destroy

Просмотреть файл

@ -0,0 +1,557 @@
#Cloud Files™ (storage)
This document explains how to get started using Cloud Files with Fog. It assumes you have read the [Getting Started with Fog and the Rackspace Open Cloud](getting_started.md) document.
## Starting irb console
Start by executing the following command:
irb
Once `irb` has launched you need to require the Fog library.
If using Ruby 1.8.x execute:
require 'rubygems'
require 'fog'
If using Ruby 1.9.x execute:
require 'fog'
## Create Service
Next, create a connection to Cloud Files.
Using a US-based account:
service = Fog::Storage.new({
:provider => 'Rackspace', # Rackspace Fog provider
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:rackspace_region => :ord, # Defaults to :dfw
:connection_options => {} # Optional
})
Using a UK-based account:
service = Fog::Storage.new({
:provider => 'Rackspace', # Rackspace Fog provider
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT,
:rackspace_region => :lon,
:connection_options => {} # Optional
})
To learn more about obtaining cloud credentials refer to the [Getting Started with Fog and the Rackspace Open Cloud](getting_started.md) document.
By default `Fog::Storage` will authenticate against the US authentication endpoint and connect to the DFW region. You can specify alternative authentication endpoints using the key `:rackspace_auth_url`. Please refer to [Alternate Authentication Endpoints](http://docs.rackspace.com/auth/api/v2.0/auth-client-devguide/content/Endpoints-d1e180.html) for a list of alternative Rackspace authentication endpoints.
Alternative regions are specified using the key `:rackspace_region `. A list of regions available for Cloud Files can be found by executing the following:
identity_service = Fog::Identity({
:provider => 'Rackspace', # Rackspace Fog provider
:rackspace_username => RACKSPACE_USER_NAME, # Your Rackspace Username
:rackspace_api_key => RACKSPACE_API, # Your Rackspace API key
:rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT # Not specified for US Cloud
})
identity_service.service_catalog.display_service_regions :cloudFiles
Rackspace Private Cloud installations can skip specifying a region and directly specify their custom service endpoints using the keys `:rackspace_storage_url` and `:rackspace_cdn_url`.
**Note**: A`Fog::Storage` instance is needed for the desired region.
### Optional Service Parameters
The Storage service supports the following additional parameters:
<table>
<tr>
<th>Key</th>
<th>Description</th>
</tr>
<tr>
<td>:rackspace_servicenet</td>
<td>If set to true, the service will access Cloud Files using the internal Rackspace ServiceNet. This option should only be used for internal network connections.</td>
</tr>
<tr>
<td>:rackspace_cdn_ssl</td>
<td>If set to true, the public_url method will return the SSL based URLs.</td>
</tr>
<tr>
<td>:persistent</td>
<td>If set to true, the service will use a persistent connection.</td>
</tr>
<tr>
<td>:rackspace_storage_url</td>
<td>The endpoint for the Cloud Files service. By default, Fog::Storage will pick the appropriate endpoint for region. This option will typically only be used for Rackspace Private Cloud Access.</td>
</tr>
<tr>
<td>:rackspace_cdn_url</td>
<td>The endpoint for the CDN service. By default, Fog::Storage pick the appropriate endpoint for region. This option will typically only be used for Rackspace Private Cloud Access.</td>
</tr>
</table>
### Optional Connection Parameters
Fog supports passing additional connection parameters to its underlying HTTP library (Excon) using the `:connection_options` parameter.
<table>
<tr>
<th>Key</th>
<th>Description</th>
</tr>
<tr>
<td>:connect_timeout</td>
<td>Connection timeout (default: 60 seconds)</td>
</tr>
<tr>
<td>:read_timeout</td>
<td>Read timeout for connection (default: 60 seconds)</td> </tr>
<tr>
<td>:write_timeout</td>
<td>Write timeout for connection (default: 60 seconds)</td>
</tr>
<tr>
<td>:proxy</td>
<td>Proxy for HTTP and HTTPS connections</td>
</tr>
<tr>
<td>:ssl_ca_path</td>
<td>Path to SSL certificate authorities</td>
</tr>
<tr>
<td>:ssl_ca_file</td>
<td>SSL certificate authority file</td>
</tr>
<tr>
<td>:ssl_verify_peer</td>
<td>SSL verify peer (default: true)</td>
</tr>
<tr>
<td>:chunk_size</td>
<td>The chunk size in bytes used for block transfers. By default, Fog uses 1 MB chunks.</td>
</tr>
</table>
## Fog Abstractions
Fog provides both a **model** and **request** abstraction. The request abstraction provides the most efficient interface and the model abstraction wraps the request abstraction to provide a convenient `ActiveModel` like interface.
### Request Layer
The request abstraction maps directly to the [Cloud Files API](http://docs.rackspace.com/files/api/v1/cf-devguide/content/Overview-d1e70.html). It provides the most efficient interface to the Rackspace Open Cloud.
To see a list of requests supported by the storage service:
service.requests
This returns:
:copy_object, :delete_container, :delete_object, :get_container, :get_containers, :get_object, :get_object_https_url, :head_container, :head_containers, :head_object, :put_container, :put_object, :put_object_manifest, :post_set_meta_temp_url_key
To see a list of requests supported by the CDN service:
service.cdn.requests
This returns:
:get_containers, :head_container, :post_container, :put_container, :delete_object
#### Example Request
To request a view account details:
response = service.head_containers
This returns in the following `Excon::Response`:
#<Excon::Response:0x10283fc68 @headers={"X-Account-Bytes-Used"=>"2563554", "Date"=>"Thu, 21 Feb 2013 21:57:02 GMT", "X-Account-Meta-Temp-Url-Key"=>"super_secret_key", "X-Timestamp"=>"1354552916.82056", "Content-Length"=>"0", "Content-Type"=>"application/json; charset=utf-8", "X-Trans-Id"=>"txe934924374a744c8a6c40dd8f29ab94a", "Accept-Ranges"=>"bytes", "X-Account-Container-Count"=>"7", "X-Account-Object-Count"=>"5"}, @status=204, @body="">
To view the status of the response:
response.status
**Note**: Fog is aware of the valid HTTP response statuses for each request type. If an unexpected HTTP response status occurs, Fog will raise an exception.
To view response headers:
response.headers
This will return:
{"X-Account-Bytes-Used"=>"2563554", "Date"=>"Thu, 21 Feb 2013 21:57:02 GMT", "X-Account-Meta-Temp-Url-Key"=>"super_secret_key", "X-Timestamp"=>"1354552916.82056", "Content-Length"=>"0", "Content-Type"=>"application/json; charset=utf-8", "X-Trans-Id"=>"txe934924374a744c8a6c40dd8f29ab94a", "Accept-Ranges"=>"bytes", "X-Account-Container-Count"=>"7", "X-Account-Object-Count"=>"5"}
To learn more about `Fog::Storage` request methods refer to [rdoc](http://rubydoc.info/gems/fog/Fog/Storage/Rackspace/Real). To learn more about Excon refer to [Excon GitHub repo](https://github.com/geemus/excon).
### Model Layer
Fog models behave in a manner similar to `ActiveModel`. Models will generally respond to `create`, `save`, `destroy`, `reload` and `attributes` methods. Additionally, fog will automatically create attribute accessors.
Here is a summary of common model methods:
<table>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
<tr>
<td>create</td>
<td>
Accepts hash of attributes and creates object.<br>
Note: creation is a non-blocking call and you will be required to wait for a valid state before using resulting object.
</td>
</tr>
<tr>
<td>save</td>
<td>Saves object.<br>
Note: not all objects support updating object.</td>
</tr>
<tr>
<td>destroy</td>
<td>
Destroys object.<br>
Note: this is a non-blocking call and object deletion might not be instantaneous.
</td>
<tr>
<td>reload</td>
<td>Updates object with latest state from service.</td>
<tr>
<td>attributes</td>
<td>Returns a hash containing the list of model attributes and values.</td>
</tr>
<td>identity</td>
<td>
Returns the identity of the object.<br>
Note: This might not always be equal to object.id.
</td>
</tr>
</table>
The remainder of this document details the model abstraction.
**Note:** Fog refers to Rackspace Cloud containers as directories.
## List Directories
To retrieve a list of directories:
service.directories
This returns a collection of `Fog::Storage::Rackspace::Directory` models:
<Fog::Storage::Rackspace::Directories
[
<Fog::Storage::Rackspace::Directory
key="blue",
bytes=434266,
count=1,
cdn_cname=nil
>,
<Fog::Storage::Rackspace::Directory
key="brown",
bytes=761879,
count=1,
cdn_cname=nil
>,
...
## Get Directory
To retrieve a specific directory:
service.directories.get "blue"
**Note** As a general rule, only use `get` when you want to iterate over the contents of a `Directory`
This call is similar to...
service.directories.new :key => "blue"
... except the `get` method makes an HTTP call that returns metadata for up to the first 10,000 files. **This can be slow!**
This returns a `Fog::Storage::Rackspace::Directory` instance:
<Fog::Storage::Rackspace::Directory
key="blue",
bytes=434266,
count=1,
cdn_cname=nil
>
## Create Directory
To create a directory:
service.directories.create :key => 'backups'
To create a directory utilizing CDN:
service.directories.create :key => 'web-assets', :public => true
### Additional Parameters
The `create` method also supports the following key values:
<table>
<tr>
<th>Key</th>
<th>Description</th>
</tr>
<tr>
<td>:metadata</td>
<td>Hash containing directory metadata.</td>
</tr>
</table>
## Update Directory
Cloud Files supports updating the `public` attribute to enable/disable CDN.
To update this attribute:
directory.public = false
directory.save
## Delete Directory
To delete a directory:
directory.destroy
**Note**: Directory must be empty before it can be deleted.
## List Files
To list files in a directory:
directory.files
**Note**: File contents is not downloaded until `body` attribute is called.
## Upload Files
To upload a file into a directory:
file = directory.files.create :key => 'space.jpg', :body => File.open "space.jpg"
**Note**: For files larger than 5 GB please refer to the [Upload Large Files](#upload_large_files) section.
If you only need a `Directory` so that you can create a file (as above), you can accomplish this without
an HTTP call as below:
dir = service.directories.new :key => "blue"
file = dir.files.new(...)
file.save
This will **not** retrieve the metadata for files in the `Directory`.
However, if the `Directory` does not already exist in Cloud Files, the `save` call will return with a 404.
In this case, you will need to `save` the `Directory` first...
dir.save
... before you can...
file.save
### Additional Parameters
The `create` method also supports the following key values:
<table>
<tr>
<th>Key</th>
<th>Description</th>
</tr>
<tr>
<td>:content_type</td>
<td>The content type of the object. Cloud Files will attempt to auto detect this value if omitted.</td>
</tr>
<tr>
<td>:access_control_allow_origin</td>
<td>URLs can make Cross Origin Requests. Format is http://www.example.com. Separate URLs with a space. An asterisk (*) allows all. Please refer to <a href="http://docs.rackspace.com/files/api/v1/cf-devguide/content/CORS_Container_Header-d1e1300.html">CORS Container Headers</a> for more information.</td>
</tr>
<tr>
<td>:origin</td>
<td>The origin is the URI of the object's host.</td>
</tr>
<tr>
<td>:etag</td>
<td>The MD5 checksum of your object's data. If specified, Cloud Files will validate the integrity of the uploaded object.</td>
</tr>
<tr>
<td>:metadata</td>
<td>Hash containing file metadata.</td>
</tr>
</table>
## Upload Large Files
Cloud Files requires files larger than 5 GB to be uploaded into segments along with an accompanying manifest file. All of the segments must be uploaded to the same container.
SEGMENT_LIMIT = 5368709119.0 # 5GB -1
BUFFER_SIZE = 1024 * 1024 # 1MB
File.open(file_name) do |f|
segment = 0
until file.eof?
segment += 1
offset = 0
# upload segment to cloud files
segment_suffix = segment.to_s.rjust(10, '0')
service.put_object("my_container", "large_file/#{segment_suffix}", nil) do
if offset <= SEGMENT_LIMIT - BUFFER_SIZE
buf = file.read(BUFFER_SIZE).to_s
offset += buf.size
buf
else
''
end
end
end
end
# write manifest file
service.put_object_manifest("my_container", "large_file", 'X-Object-Manifest' => "my_container/large_file/")
Segmented files are downloaded like ordinary files. See [Download Files](#download-files) section for more information.
## Download Files
The most efficient way to download files from a private or public directory is as follows:
File.open('downloaded-file.jpg', 'w') do | f |
directory.files.get("my_big_file.jpg") do | data, remaining, content_length |
f.syswrite data
end
end
This will download and save the file in 1 MB chunks. The chunk size can be changed by passing the parameter `:chunk_size` into the `:connection_options` hash in the service constructor.
**Note**: The `body` attribute of file will be empty if a file has been downloaded using this method.
If a file object has already been loaded into memory, you can save it as follows:
File.open('germany.jpg', 'w') {|f| f.write(file_object.body) }
**Note**: This method is more memory intensive as the entire object is loaded into memory before saving the file as in the example above.
## Accessing Files Through CDN
The CDN service offers several different URLs to access your files.
The simplest is with the default container URL. This can be accessed as follows:
file.public_url
For a more user-friendly URL, you can create a CNAME DNS record pointing to the URL generated by the `public_url` method. Then set the CNAME on the `Directory` object using the attribute `cdn_cname`. Note, that the `cdn_cname` attribute does not persist and will need to be specified every time a directory object is retrieved.
To access the file using SSL, you need to specify the option `:rackspace_cdn_ssl => true` when creating `Fog::Storage` service. This will cause the `public_url` method to return the SSL-secured URL.
To stream content use the following:
file.streaming_url
To stream video for iOS devices without needing to convert your video use the following:
file.ios_url
## Metadata
You can access metadata as an attribute on both `Fog::Storage::Rackspace::Directory` and `Fog::Storage::Rackspace::File`.
This example demonstrates how to iterate through a directory's metadata:
directory.metadata.each_pair {|metadatum| puts "#{metadatum.key}: #{metadatum.value}" }
You can update and retrieve metadata in a manner similar to a hash:
directory.metadata[:thumbnails]
file.metadata[:environment] = "development"
Directory metadata is saved when the directory is saved and file metadata is set when the file is saved:
directory.save
file.save
Metadata is reloaded when directory or file is reloaded:
directory.reload
file.reload
## Copy File
Cloud Files supports copying files. To copy files into a container named "trip" with a name of "europe.jpg" do the following:
file.copy("trip", "europe.jpg")
To move or rename a file, perform a copy operation and then delete the old file:
file.copy("trip", "germany.jpg")
file.destroy
## Delete File
To delete a file:
file.destroy
## CDN Purge
To immediately remove a file from the CDN network use the following:
file.purge_from_cdn
You may only purge up to 25 objects per day and thus this should only be used in situations where there could be serious personal, business, or security consequences if the object remained in the CDN. To purge a directory, please contact Rackspace support.
**Note**: You may only **PURGE** up to 25 objects per day. Any attempt to purge more than this will result in a 498 status code error (Rate Limited).
## Account Information
To view Cloud Files usage execute the following:
service.account
This returns a `Fog::Storage::Rackspace::Account` instance:
<Fog::Storage::Rackspace::Account
meta_temp_url_key="lkkl23jl2j3",
container_count=13,
bytes_used=2563554,
object_count=5
>
## Examples
Example code using Cloud Files can be found [here](https://github.com/fog/fog/tree/master/lib/fog/rackspace/examples).
## Additional Resources
* [fog.io](http://fog.io/)
* [Fog rdoc](http://rubydoc.info/gems/fog/)
* [Fog Github repo](https://github.com/fog/fog)
* [Fog Github Issues](https://github.com/fog/fog/issues)
* [Excon Github repo](https://github.com/geemus/excon)
* [Cloud Files API](http://docs.rackspace.com/files/api/v1/cf-devguide/content/Overview-d1e70.html)
## Support and Feedback
Your feedback is appreciated! If you have specific issues with the **fog** SDK, you should file an [issue via Github](https://github.com/fog/fog/issues).
For general feedback and support requests, send an email to: <sdk-support@rackspace.com>.

Просмотреть файл

@ -0,0 +1,33 @@
module Fog
module Rackspace
module Errors
def self.included(mod)
mod.class_eval <<-'EOS', __FILE__, __LINE__
class NotFound < Fog::Service::NotFound
attr_reader :region, :status_code, :transaction_id
def to_s
status = status_code ? "HTTP #{status_code}" : "HTTP <Unknown>"
message = region ? "resource not found in #{region} region" : super
"[#{status} | #{transaction_id}] #{message}"
end
def self.slurp(error, service=nil)
exception = NotFound.new
exception.instance_variable_set(:@region, service.region) if service && service.respond_to?(:region)
exception.instance_variable_set(:@status_code, error.response.status) rescue nil
exception.set_transaction_id(error, service)
exception
end
def set_transaction_id(error, service)
return unless service && service.respond_to?(:request_id_header) && error.response
@transaction_id = error.response.headers[service.request_id_header]
end
end
EOS
end
end
end
end

Просмотреть файл

@ -0,0 +1,47 @@
# Getting Started Examples
## Download
Examples using the Rackspace Open Cloud and Fog can be found in the [fog repository](https://github.com/fog/fog) under the directory `fog/lib/fog/rackspace/examples`.
This repository can be downloaded via `git` by executing the following:
git clone git://github.com/fog/fog.git
Optionally you can download a zip by clicking on this [link](https://github.com/fog/fog/archive/master.zip).
## Requirements
Examples require the following:
* Rackspace Open Cloud account
* Ruby 1.8.x or 1.9.x
* `fog` gem
For more information please refer to the [Getting Started with Fog and the Rackspace Open Cloud](https://github.com/fog/fog/blob/master/lib/fog/rackspace/docs/getting_started.md) document.
## Credentials
Examples will prompt for Rackspace Open Cloud credentials. Prompts can be skipped by creating a `.fog` file in the user's home directory. This is an example of a `.fog` file for the Rackspace Open Cloud:
default:
rackspace_username: RACKSPACE_USERNAME
rackspace_api_key: RACKSPACE_API_KEY
**Note:** Replace capitalized values with the appropriate credential information.
## Executing
To execute scripts using `bundler`:
bundle exec ruby <script>
To execute scripts without `bundler`:
ruby <script>
## Support and Feedback
Your feedback is appreciated! If you have specific issues with the **fog** SDK, developers should file an [issue via Github](https://github.com/fog/fog/issues).
For general feedback and support requests, send an email to: <sdk-support@rackspace.com>.

Просмотреть файл

@ -0,0 +1,66 @@
#!/usr/bin/env ruby
# This example demonstrates adding a poicy to an auto scaling group with the Rackpace Open Cloud
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
def get_user_input_as_int(prompt)
str = get_user_input(prompt)
str.to_i
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
def select_group(groups)
abort "\nThere are not any scaling groups in the Chicago region. Try running create_scaling_group.rb\n\n" if groups.empty?
puts "\nSelect Group For New Policy:\n\n"
groups.each_with_index do |group, i|
config = group.group_config
puts "\t #{i}. #{config.name}"
end
select_str = get_user_input "\nEnter Group Number"
groups[select_str.to_i]
end
# create auto scaling service
auto_scale_service = Fog::Rackspace::AutoScale.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord # Use Chicago Region
})
# retrieve list of scaling groups
groups = auto_scale_service.groups
# prompt group
group = select_group(groups)
# prompt for policy name
policy_name = get_user_input "Enter name for policy"
# prompt for cool down period for policy
cooldown = get_user_input_as_int "Enter cool down period in seconds"
# prompt for change increment
change = get_user_input_as_int "Enter change increment"
group.policies.create :name => policy_name, :cooldown => cooldown, :type => 'webhook', :change => change
puts "\nPolicy #{policy_name} was successfully added to group"

Просмотреть файл

@ -0,0 +1,74 @@
#!/usr/bin/env ruby
# This example demonstrates adding a webhook to an auto scaling group with the Rackpace Open Cloud
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
def select_group(groups)
abort "\nThere are no groups in the Chicago region. Try running create_scaling_group.rb\n\n" if groups.empty?
puts "\nSelect Group With Policy:\n\n"
groups.each_with_index do |group, i|
config = group.group_config
puts "\t #{i}. #{config.name}"
end
select_str = get_user_input "\nEnter Group Number"
groups[select_str.to_i]
end
def select_policy(policies)
abort "\nThere are no policies for this scaling group. Try running add_policy.rb\n\n" if policies.empty?
puts "\nSelect Policy Triggered By Webhook:\n\n"
policies.each_with_index do |policy, i|
puts "\t #{i}. #{policy.name}"
end
select_str = get_user_input "\nEnter Policy Number"
policies[select_str.to_i]
end
# create auto scaling service
auto_scale_service = Fog::Rackspace::AutoScale.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord # Use Chicago Region
})
# retrieve list of scaling groups
groups = auto_scale_service.groups
# prompt for group
group = select_group(groups)
# retrieve list of policies for group
policies = group.policies
# prompt for policy to delete
policy = select_policy(policies)
# prompt for webhook name
webhook_name = get_user_input "Enter name for webhook"
# create webhook
webhook = policy.webhooks.create :name => webhook_name
puts "\nWebhook #{webhook.name} was successfully added - #{webhook.execution_url}"

Просмотреть файл

@ -0,0 +1,111 @@
#!/usr/bin/env ruby
# This example demonstrates creating an auto scaling group with the Rackpace Open Cloud
require 'fog'
require 'fog/rackspace/models/auto_scale/group_builder'
# UUID for INTERNET
INTERNET = '00000000-0000-0000-0000-000000000000'
# UUID for Rackspace's service net
SERVICE_NET = '11111111-1111-1111-1111-111111111111'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
def get_user_input_as_int(prompt)
str = get_user_input(prompt)
str.to_i
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
def select_image(images)
puts "\nSelect Image For Server:\n\n"
images.each_with_index do |image, i|
puts "\t #{i}. #{image.name}"
end
select_str = get_user_input "\nEnter Image Number"
images[select_str.to_i]
end
# create auto scaling service
auto_scale_service = Fog::Rackspace::AutoScale.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord # Use Chicago Region
})
# create Next Generation Cloud Server service to get list of flavors
compute_service = Fog::Compute.new({
:provider => 'rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:version => :v2, # Use Next Gen Cloud Servers
:rackspace_region => :ord # Use Chicago Region
})
# prompt for scaling group name
scaling_group_name = get_user_input "Enter name of scaling group"
# prompt for cool down period
cooldown = get_user_input_as_int "Enter cool down period in seconds"
# prompt for miniumum number of entities
min_entities = get_user_input_as_int "Enter minimum number of servers"
# prompt for max number of entities
max_entities = get_user_input_as_int "Enter maximum number of servers"
# retrieve list of images from computer service
print "Loading available server images...."
images = compute_service.images.all
puts "[DONE]"
# prompt for server image
image = select_image(images)
# pick first server flavor
flavor = compute_service.flavors.first
attributes = {
:server_name => "autoscale_server",
:image => image,
:flavor => flavor,
:networks => [INTERNET, SERVICE_NET],
:personality => [
{
"path" => "/root/.csivh",
"contents" => "VGhpcyBpcyBhIHRlc3QgZmlsZS4="
}
],
:max_entities => max_entities,
:min_entities => min_entities,
:cooldown => cooldown,
:name => scaling_group_name,
:metadata => { "created_by" => "autoscale sample script" },
:launch_config_type => :launch_server
}
# Use builder to create group
group = Fog::Rackspace::AutoScale::GroupBuilder.build(auto_scale_service, attributes)
# save the built group
group.save
puts "\nScaling Group #{scaling_group_name} (#{group.id}) was created!"
puts "State: #{group.state}"

Просмотреть файл

@ -0,0 +1,71 @@
#!/usr/bin/env ruby
# This example demonstrates deleting an auto scaling policy with the Rackpace Open Cloud
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
def select_group(groups)
abort "\nThere are no groups in the Chicago region. Try running create_scaling_group.rb\n\n" if groups.empty?
puts "\nSelect Group With Policy:\n\n"
groups.each_with_index do |group, i|
config = group.group_config
puts "\t #{i}. #{config.name}"
end
select_str = get_user_input "\nEnter Group Number"
groups[select_str.to_i]
end
def select_policy(policies)
abort "\nThere are no policies for this scaling group. Try running add_policy.rb\n\n" if policies.empty?
puts "\nSelect Policy To Delete:\n\n"
policies.each_with_index do |policies, i|
puts "\t #{i}. #{policies.name}"
end
select_str = get_user_input "\nEnter Policy Number"
policies[select_str.to_i]
end
# create auto scaling service
auto_scale_service = Fog::Rackspace::AutoScale.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord # Use Chicago Region
})
# retrieve list of scaling groups
groups = auto_scale_service.groups
# prompt for group
group = select_group(groups)
# retrieve list of policies for group
policies = group.policies
# prompt for policy to delete
policy = select_policy(policies)
# delete policy
policy.destroy
puts "\nPolicy '#{policy.name}' has been destroyed\n\n"

Просмотреть файл

@ -0,0 +1,59 @@
#!/usr/bin/env ruby
# This example demonstrates deleting an auto scaling group with the Rackpace Open Cloud
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
def select_group(groups)
abort "\nThere are not any groups to delete in the Chicago region. Try running create_scaling_group.rb\n\n" if groups.empty?
puts "\nSelect Group To Delete:\n\n"
groups.each_with_index do |group, i|
config = group.group_config
puts "\t #{i}. #{config.name}"
end
select_str = get_user_input "\nEnter Group Number"
groups[select_str.to_i]
end
# create auto scaling service
auto_scale_service = Fog::Rackspace::AutoScale.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord # Use Chicago Region
})
# retrieve list of scaling groups
groups = auto_scale_service.groups
# prompt for group to delete
group = select_group(groups)
# min_entities and max_entities must be 0 before deleting group
config = group.group_config
config.min_entities = 0
config.max_entities = 0
config.save
# delete group
group.destroy
puts "\nScaling Group '#{config.name}' has been destroyed\n\n"

Просмотреть файл

@ -0,0 +1,89 @@
#!/usr/bin/env ruby
# This example demonstrates delete a webhook from an auto scaling group with the Rackpace Open Cloud
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
def select_group(groups)
abort "\nThere are no groups in the Chicago region. Try running create_scaling_group.rb\n\n" if groups.empty?
puts "\nSelect Group With Policy:\n\n"
groups.each_with_index do |group, i|
config = group.group_config
puts "\t #{i}. #{config.name}"
end
select_str = get_user_input "\nEnter Group Number"
groups[select_str.to_i]
end
def select_policy(policies)
abort "\nThere are no policies for this scaling group. Try running add_policy.rb\n\n" if policies.empty?
puts "\nSelect Policy With Webhook:\n\n"
policies.each_with_index do |policy, i|
puts "\t #{i}. #{policy.name}"
end
select_str = get_user_input "\nEnter Policy Number"
policies[select_str.to_i]
end
def select_webhook(webhooks)
abort "\nThere are no webhooks for this policy. Try running add_webhook.rb\n\n" if webhooks.empty?
puts "\nSelect Webhook:\n\n"
webhooks.each_with_index do |webhook, i|
puts "\t #{i}. #{webhook.name}"
end
select_str = get_user_input "\nEnter Webhook Number"
webhooks[select_str.to_i]
end
# create auto scaling service
auto_scale_service = Fog::Rackspace::AutoScale.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord # Use Chicago Region
})
# retrieve list of scaling groups
groups = auto_scale_service.groups
# prompt for group
group = select_group(groups)
# retrieve list of policies for group
policies = group.policies
# prompt for policy
policy = select_policy(policies)
# retrieve list of webhooks for policy
webhooks = policy.webhooks
# prompt for webhook
webhook = select_webhook(webhooks)
# delete webhook
webhook.destroy
puts "Webhook '#{webhook.name} was destroyed"

Просмотреть файл

@ -0,0 +1,116 @@
#!/usr/bin/env ruby
# This example demonstrates creating a snapshot from a Cloud Block Storage volume with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "\n#{prompt}: "
gets.chomp
end
def select_server(servers)
abort "\nThere are not any servers in the Chicago region. Try running create_server.rb\n\n" if servers.empty?
puts "\nSelect Server For Volume Detachment:\n\n"
servers.each_with_index do |server, i|
puts "\t #{i}. #{server.name} [#{server.public_ip_address}]"
end
delete_str = get_user_input "\nEnter Server Number"
servers[delete_str.to_i]
end
def select_attachment(attachments)
abort "\nThis server does not contain any volumes in the Chicago region. Try running server_attachments.rb\n\n" if attachments.empty?
puts "\nSelect Volume To Detach:\n\n"
attachments.each_with_index do |attachment, i|
puts "\t #{i}. #{attachment.device}"
end
delete_str = get_user_input "\nEnter Volume Number"
attachments[delete_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
#create Next Generation Cloud Server service
compute_service = Fog::Compute.new({
:provider => 'rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:version => :v2, # Use Next Gen Cloud Servers
:rackspace_region => :ord #Use Chicago Region
})
#create Cloud Block Storage service
cbs_service = Fog::Rackspace::BlockStorage.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# retrieve list of servers
servers = compute_service.servers
# prompt user for server
server = select_server(servers)
# get attached volumes --also know as attachments
attachments = server.attachments
# prompt user for volume to detach
attachment = select_attachment(attachments)
# prompt for snapshot name
snapshot_name = get_user_input "Enter Snapshot Name"
puts "\n\n"
puts "******************** NOTE ******************************************"
puts "* Volume must be unmounted from operating system before detaching. *"
puts "* This script assumes volume has been unmounted. *"
puts "********************************************************************\n\n"
volume = cbs_service.volumes.get attachment.volume_id
# The snapshot process requires all writes to be flushed to disk. This requires unmounting the file systems or detaching the volume.
puts "Detaching Volume #{volume.display_name}"
attachment.detach
volume.wait_for { ready? }
puts "Now Creating Snapshot #{snapshot_name}"
snapshot = cbs_service.snapshots.create :display_name => snapshot_name, :volume_id => attachment.volume_id
begin
# Check every 5 seconds to see if snapshot is in the available state (ready?).
# If the available has not been built in 5 minutes (600 seconds) an exception will be raised.
snapshot.wait_for(600, 5) do
print "."
STDOUT.flush
ready?
end
puts "[DONE]\n\n"
puts "Re-attaching Volume #{volume.display_name}"
attachment.save
rescue Fog::Errors::TimeoutError
puts "[TIMEOUT]\n\n"
puts "The snapshot #{snapshot.display_name} is still being preformed and is taking longer to complete than expected."
puts "You can continute to monitor the process through the web console at https://mycloud.rackspace.com/\n\n"
end

Просмотреть файл

@ -0,0 +1,58 @@
#!/usr/bin/env ruby
# This example demonstrates creating Cloud Block Storage volume with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "\n#{prompt}: "
gets.chomp
end
def select_volume_type(volume_types)
puts "\nSelect Volume Type:\n\n"
volume_types.each_with_index do |volume_type, i|
puts "\t #{i}. #{volume_type.name}"
end
selected_str = get_user_input "Enter Volume Type Number"
volume_types[selected_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Cloud Block Storage service
service = Fog::Rackspace::BlockStorage.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# retrieve list of volume types
volume_types = service.volume_types
#prompt user for volume type
volume_type = select_volume_type(volume_types)
# prompt for volume size
volume_size = get_user_input "Enter Size of Volume (100 GB Minimum)"
# prompt for name of volume
volume_name = get_user_input "Enter Name for Volume"
#create volume
volume = service.volumes.create(:size => volume_size, :display_name => volume_name, :volume_type => volume_type.name)
puts "\nVolume #{volume_name} is being created.\n\n"
puts "To delete the volume please execute the delete_volume.rb script\n\n"

Просмотреть файл

@ -0,0 +1,53 @@
#!/usr/bin/env ruby
# This example demonstrates deleting Cloud Block Storage volume with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "\n#{prompt}: "
gets.chomp
end
def select_volume(volumes)
abort "\nThere are not any volumes to delete in the Chicago region. Try running create_volume.rb\n\n" if volumes.empty?
puts "\nSelect Volume:\n\n"
volumes.each_with_index do |volume, i|
puts "\t #{i}. #{volume.display_name}"
end
selected_str = get_user_input "Enter Volume Type Number"
volumes[selected_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Cloud Block Storage service
service = Fog::Rackspace::BlockStorage.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# retrieve list of volumes
volumes = service.volumes
# prompt user for volume
volume = select_volume(volumes)
# delete volume
volume.destroy
puts "\nVolume #{volume.display_name} is being destroyed.\n\n"

Просмотреть файл

@ -0,0 +1,96 @@
#!/usr/bin/env ruby
# This example demonstrates creating a server with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
require 'base64' #required to encode files for personality functionality
require 'sshkey' #required to generate ssh keys. 'gem install sshkey'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# Generates a ssh key using the SSHKey library. The private key is avaialble via
# the '.private_key' and the public key is avaialble via '.ssh_public_key'
def generate_ssh_key
SSHKey.generate
end
# create Next Generation Cloud Server service
service = Fog::Compute.new({
:provider => 'rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:version => :v2, # Use Next Gen Cloud Servers
:rackspace_region => :ord #Use Chicago Region
})
# pick the first flavor
flavor = service.flavors.first
# pick the first Ubuntu image we can find
image = service.images.find {|image| image.name =~ /Ubuntu/}
# prompt for server name
server_name = get_user_input "\nEnter Server Name"
# generate the ssh key
ssh_key = generate_ssh_key
# reload flavor in order to retrieve all of its attributes
flavor.reload
puts "\nNow creating server '#{server_name}' the following with specifications:\n"
puts "\t* #{flavor.ram} MB RAM"
puts "\t* #{flavor.disk} GB"
puts "\t* #{flavor.vcpus} CPU(s)"
puts "\t* #{image.name}"
puts "\n"
begin
# bootstrap server
server = service.servers.bootstrap :name => server_name,
:flavor_id => flavor.id,
:image_id => image.id,
:private_key => ssh_key.private_key,
:public_key => ssh_key.ssh_public_key
if server.ready?
puts "[DONE]\n\n"
puts "The server has been successfully created.\n"
puts "Write the following ssh keys to you ~/.ssh directory in order to log in\n\n"
puts "+++++++++++PRIVATE_KEY (~/.ssh/fog_key)++++++++++++"
puts ssh_key.private_key
puts "++++++++++PUBLIC_KEY (~/.ssh/fog_key.pub)++++++++++"
puts ssh_key.ssh_public_key
puts "+++++++++++++++++++++++++++++++++++++++++++++++++++i\n\n"
puts "You can then log into the server using the following command\n"
puts "ssh #{server.username}@#{server.public_ip_address}\n\n"
else
puts "An error occured, please try again"
end
rescue Fog::Errors::TimeoutError
puts "[TIMEOUT]\n\n"
puts "This server is currently #{server.progress}% into the build process and is taking longer to complete than expected."
puts "You can continute to monitor the build process through the web console at https://mycloud.rackspace.com/\n\n"
end
puts "To delete the server please execute the delete_server.rb script\n\n"

Просмотреть файл

@ -0,0 +1,59 @@
#!/usr/bin/env ruby
# This example demonstrates creating a server image with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
def select_server(servers)
abort "\nThere are not any servers available to image in the Chicago region. Try running create_server.rb\n\n" if servers.empty?
puts "\nSelect Server To Image:\n\n"
servers.each_with_index do |server, i|
puts "\t #{i}. #{server.name} [#{server.public_ip_address}]"
end
selected_str = get_user_input "\nEnter Server Number"
servers[selected_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Next Generation Cloud Server service
service = Fog::Compute.new({
:provider => 'rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:version => :v2, # Use Next Gen Cloud Servers
:rackspace_region => :ord #Use Chicago Region
})
# retrieve list of servers
servers = service.servers
# prompt user for server
server = select_server(servers)
# prompt user for image name
image_name = get_user_input "Enter Image Name"
# creates image for server
server.create_image image_name
puts "\nImage #{image_name} is being created for server #{server.name}.\n\n"
puts "To delete the image please execute the delete_image.rb script\n\n"

Просмотреть файл

@ -0,0 +1,81 @@
#!/usr/bin/env ruby
# This example demonstrates creating a private network and attaching it to a new server with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
# UUID for INTERNET
INTERNET = '00000000-0000-0000-0000-000000000000'
# UUID for Rackspace's service net
SERVICE_NET = '11111111-1111-1111-1111-111111111111'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Next Generation Cloud Server service
service = Fog::Compute.new({
:provider => 'rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:version => :v2, # Use Next Gen Cloud Servers
:rackspace_region => :ord #Use Chicago Region
})
#create private network called my_private_net with an ip range between 192.168.0.1 - 192.168.0.255 (Note this will accept IPv6 CIDRs as well)
net = service.networks.create :label => 'my_private_net', :cidr => '192.168.0.0/24'
puts "\nCreating #{net.label} Network with CIDR #{net.cidr}"
# pick the first flavor
flavor = service.flavors.first
# pick the first Ubuntu image we can find
image = service.images.find {|image| image.name =~ /Ubuntu/}
# Create a server called alphabits connected our private network as well as the internet
server = service.servers.create :name => 'alphabits',
:flavor_id => flavor.id,
:image_id => image.id,
:networks => [net.id, INTERNET]
puts "\nNow creating server '#{server.name}' connected the the Internet and '#{net.label}'\n"
begin
# Check every 5 seconds to see if server is in the active state (ready?).
# If the server has not been built in 5 minutes (600 seconds) an exception will be raised.
server.wait_for(600, 5) do
print "."
STDOUT.flush
ready?
end
puts "[DONE]\n\n"
puts "The server has been successfully created, to login onto the server:\n\n"
puts "\t ssh #{server.username}@#{server.public_ip_address}\n\n"
rescue Fog::Errors::TimeoutError
puts "[TIMEOUT]\n\n"
puts "This server is currently #{server.progress}% into the build process and is taking longer to complete than expected."
puts "You can continute to monitor the build process through the web console at https://mycloud.rackspace.com/\n\n"
end
puts "The #{server.username} password is #{server.password}\n\n"
puts "To delete the server and private network please execute the delete_network.rb script\n\n"

Просмотреть файл

@ -0,0 +1,87 @@
#!/usr/bin/env ruby
# This example demonstrates creating a server with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
require "base64" #required to encode files for personality functionality
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Next Generation Cloud Server service
service = Fog::Compute.new({
:provider => 'rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:version => :v2, # Use Next Gen Cloud Servers
:rackspace_region => :ord #Use Chicago Region
})
# pick the first flavor
flavor = service.flavors.first
# pick the first Ubuntu image we can find
image = service.images.find {|image| image.name =~ /Ubuntu/}
# prompt for server name
server_name = get_user_input "\nEnter Server Name"
# create server
server = service.servers.create :name => server_name,
:flavor_id => flavor.id,
:image_id => image.id,
:metadata => { 'fog_sample' => 'true'},
:personality => [{
:path => '/root/fog.txt',
:contents => Base64.encode64('Fog was here!')
}]
# reload flavor in order to retrieve all of its attributes
flavor.reload
puts "\nNow creating server '#{server.name}' the following with specifications:\n"
puts "\t* #{flavor.ram} MB RAM"
puts "\t* #{flavor.disk} GB"
puts "\t* #{flavor.vcpus} CPU(s)"
puts "\t* #{image.name}"
puts "\n"
begin
# Check every 5 seconds to see if server is in the active state (ready?).
# If the server has not been built in 5 minutes (600 seconds) an exception will be raised.
server.wait_for(600, 5) do
print "."
STDOUT.flush
ready?
end
puts "[DONE]\n\n"
puts "The server has been successfully created, to login onto the server:\n\n"
puts "\t ssh #{server.username}@#{server.public_ip_address}\n\n"
rescue Fog::Errors::TimeoutError
puts "[TIMEOUT]\n\n"
puts "This server is currently #{server.progress}% into the build process and is taking longer to complete than expected."
puts "You can continute to monitor the build process through the web console at https://mycloud.rackspace.com/\n\n"
end
puts "The #{server.username} password is #{server.password}\n\n"
puts "To delete the server please execute the delete_server.rb script\n\n"

Просмотреть файл

@ -0,0 +1,60 @@
#!/usr/bin/env ruby
# This example demonstrates deleting a server image with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
def select_image(snapshot_images)
abort "\nThere are not any images to delete in the Chicago region. Try running create_image.rb\n\n" if snapshot_images.empty?
puts "\nSelect Image To Delete:\n\n"
snapshot_images.each_with_index do |image, i|
puts "\t #{i}. #{image.name}"
end
delete_str = get_user_input "\nEnter Image Number"
snapshot_images[delete_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Next Generation Cloud Server service
service = Fog::Compute.new({
:provider => 'rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:version => :v2, # Use Next Gen Cloud Servers
:rackspace_region => :ord #Use Chicago Region
})
# retrieve list of images
images = service.images
# select all of the snapshot type images. base images are not user deletable
snapshot_images = images.select do |image|
image.metadata["image_type"] == "snapshot"
end
# prompt user for image to delete
image = select_image(snapshot_images)
# delete image
image.destroy
puts "\n#{image.name} has been destroyed\n\n"

Просмотреть файл

@ -0,0 +1,78 @@
#!/usr/bin/env ruby
# This example demonstrates deletes a private network and attaching it to a new server with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def wait_for_server_deletion(server)
begin
server.wait_for { state = 'DELETED' }
rescue Fog::Compute::RackspaceV2::NotFound => e
# do nothing
end
end
# I have notice that cloud networks is slow to acknowledge deleted servers. This method tries to mitigate this.
def delete_network(network)
attempt = 0
begin
network.destroy
rescue Fog::Compute::RackspaceV2::ServiceError => e
if attempt == 3
puts "Unable to delete #{network.label}"
return false
end
puts "Network #{network.label} Delete Fail Attempt #{attempt}- #{e.inspect}"
attempt += 1
sleep 60
retry
end
return true
end
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Next Generation Cloud Server service
service = Fog::Compute.new({
:provider => 'rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:version => :v2, # Use Next Gen Cloud Servers
:rackspace_region => :ord #Use Chicago Region
})
# NOTE: The network must not be connected to any servers before deletion
# Find alpha bits server
server = service.servers.find {|s| s.name == 'alphabits'}
puts "\n"
if server
puts "Deleting alphabits server..."
server.destroy
else
puts "Unable to find server alphabits"
end
wait_for_server_deletion(server)
network = service.networks.find {|n| n.label == 'my_private_net'}
delete_network(network)
puts "The network '#{network.label}' has been successfully deleted"

Просмотреть файл

@ -0,0 +1,55 @@
#!/usr/bin/env ruby
# This example demonstrates how to delete servers with Fog and the Rackspace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
def select_server(servers)
abort "\nThere are not any servers to delete in the Chicago region. Try running create_server.rb\n\n" if servers.empty?
puts "\nSelect Server To Delete:\n\n"
servers.each_with_index do |server, i|
puts "\t #{i}. #{server.name} [#{server.public_ip_address}]"
end
delete_str = get_user_input "\nEnter Server Number"
servers[delete_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
#create Next Generation Cloud Server service
service = Fog::Compute.new({
:provider => 'rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:version => :v2, # Use Next Gen Cloud Servers
:rackspace_region => :ord #Use Chicago Region
})
#retrieve list of servers
servers = service.servers
#prompt user for server
server = select_server(servers)
#destroy server
server.destroy
puts "\nServer #{server.name} has been destroyed\n"

Просмотреть файл

@ -0,0 +1,93 @@
#!/usr/bin/env ruby
# This example demonstrates working with server and volumes on the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
def select_server(servers)
abort "\nThere are not any servers in the Chicago region. Try running create_server.rb\n\n" if servers.empty?
puts "\nSelect Server For Volume Detachment:\n\n"
servers.each_with_index do |server, i|
puts "\t #{i}. #{server.name} [#{server.public_ip_address}]"
end
delete_str = get_user_input "\nEnter Server Number"
servers[delete_str.to_i]
end
def select_attachment(attachments)
abort "\nThis server does not contain any volumes in the Chicago region. Try running server_attachments.rb\n\n" if attachments.empty?
puts "\nSelect Volume To Detach:\n\n"
attachments.each_with_index do |attachment, i|
puts "\t #{i}. #{attachment.device}"
end
delete_str = get_user_input "\nEnter Volume Number"
attachments[delete_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
#create Next Generation Cloud Server service
compute_service = Fog::Compute.new({
:provider => 'rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:version => :v2, # Use Next Gen Cloud Servers
:rackspace_region => :ord #Use Chicago Region
})
cbs_service = Fog::Rackspace::BlockStorage.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# retrieve list of servers
servers = compute_service.servers
# prompt user for server
server = select_server(servers)
# get attached volumes --also know as attachments
attachments = server.attachments
# prompt user for volume to detach
attachment = select_attachment(attachments)
volume = cbs_service.volumes.get attachment.volume_id
puts "Detaching Volume #{volume.display_name} From Server #{server.name}"
attachment.detach
puts "\n"
delete_confirm = get_user_input "Would You Like To Destroy Volume #{volume.display_name} (y/n)"
if delete_confirm.downcase == 'y'
# wait for server to finish detaching before attempting to delete
volume.wait_for(600) do
print "."
STDOUT.flush
ready? && attachments.empty?
end
volume.destroy
puts "\n\nThe Volume Has been Destroyed"
end

Просмотреть файл

@ -0,0 +1,106 @@
#!/usr/bin/env ruby
# This example demonstrates how to resize servers with Fog and the Rackspace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
def select_flavor(flavors, server)
puts "\nSelect New Flavor Size:\n\n"
flavors.each_with_index do |flavor, i|
next if server.flavor_id == flavor.id
puts "\t #{i}. #{flavor.name}"
end
selected_flavor_str = get_user_input "\nEnter Flavor Number"
flavors[selected_flavor_str.to_i]
end
def select_server(servers)
abort "\nThere are not any servers to resize in the Chicago region. Try running create_server.rb\n\n" if servers.empty?
puts "\nSelect Server Resize:\n\n"
servers.each_with_index do |server, i|
puts "\t #{i}. #{server.name} [#{server.public_ip_address}]"
end
selected_str = get_user_input "\nEnter Server Number"
servers[selected_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
#create Next Generation Cloud Server service
service = Fog::Compute.new({
:provider => 'rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:version => :v2, # Use Next Gen Cloud Servers
:rackspace_region => :ord #Use Chicago Region
})
#retrieve list of servers
servers = service.servers
#prompt user for server
server = select_server(servers)
# retrieve list of avaliable flavors
flavors = service.flavors
# prompt user for flavor
selected_flavor = select_flavor(flavors, server)
# resize server
server.resize selected_flavor.id
puts "\n"
# wait for the resize process to start
server.wait_for { ready?('RESIZE') }
begin
# Check every 5 seconds to see if server is in the VERIFY_RESIZE state.
# If the server has not been built in 5 minutes (600 seconds) an exception will be raised.
server.wait_for(1200, 5) do
print "."
STDOUT.flush
ready?('VERIFY_RESIZE', ['ACTIVE', 'ERROR'])
end
puts "[DONE]\n\n"
puts "Server Has Been Successfully Resized!"
action = get_user_input "Press 'C' To Confirm Or 'R' to Revert Resize (R/C)"
case action.upcase
when 'C'
puts "\nConfirming Resize Operation"
server.confirm_resize
when 'R'
puts "\nReverting Resize Operation"
server.revert_resize
else
puts "\nUnrecognized Input. Exiting."
end
rescue Fog::Errors::TimeoutError
puts "[TIMEOUT]\n\n"
puts "This server is currently #{server.progress}% into the resize process and is taking longer to complete than expected."
puts "You can continute to monitor the build process through the web console at https://mycloud.rackspace.com/\n\n"
end

Просмотреть файл

@ -0,0 +1,68 @@
#!/usr/bin/env ruby
# This example demonstrates working with server and volumes on the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
def select_server(servers)
abort "\nThere are not any servers in the Chicago region. Try running create_server.rb\n\n" if servers.empty?
puts "\nSelect Server For Attachment:\n\n"
servers.each_with_index do |server, i|
puts "\t #{i}. #{server.name} [#{server.public_ip_address}]"
end
delete_str = get_user_input "\nEnter Server Number"
servers[delete_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
#create Next Generation Cloud Server service
compute_service = Fog::Compute.new({
:provider => 'rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:version => :v2, # Use Next Gen Cloud Servers
:rackspace_region => :ord #Use Chicago Region
})
cbs_service = Fog::Rackspace::BlockStorage.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# retrieve list of servers
servers = compute_service.servers
# prompt user for server
server = select_server(servers)
# prompt for volume name
volume_name = get_user_input "Enter Volume Name"
puts "\nCreating Volume\n"
volume = cbs_service.volumes.create(:size => 100, :display_name => volume_name)
puts "\nAttaching volume\n"
attachment = server.attach_volume volume
puts "\nVolume #{volume.display_name} has been attached to #{server.name} on device #{attachment.device}\n\n"
puts "To detach volume please execute the detach_volume.rb script\n\n"

Просмотреть файл

@ -0,0 +1,83 @@
#!/usr/bin/env ruby
# This example demonstrates working with server metadata on the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require './lib/fog'
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
def print_metadata(server)
server.metadata.each do |metadatum|
puts "\t#{metadatum.key}: #{metadatum.value}"
end
puts "\n"
end
#create Next Generation Cloud Server service
service = Fog::Compute.new({
:provider => 'rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:version => :v2, # Use Next Gen Cloud Servers
:rackspace_region => :ord #Use Chicago Region
})
# Pick the first flavor
flavor = service.flavors.first
# Pick the first Ubuntu image we can find
image = service.images.find {|image| image.name =~ /Ubuntu/}
#create server
server = service.servers.create :name => 'meta-cumulus',
:flavor_id => flavor.id,
:image_id => image.id,
:metadata => { 'color' => 'red'}
puts "Waiting for server to be created\n"
server.wait_for(600, 5) do
print "."
STDOUT.flush
ready?
end
puts "[DONE]\n\n"
puts "Initial Metadata\n"
print_metadata(server)
puts "Adding New Metadata\n"
server.metadata["environment"] = "demo"
print_metadata(server)
puts "Updating Existing Metadata\n"
server.metadata["color"] = "blue"
print_metadata(server)
puts "Saving Metadata Changes\n"
server.metadata.save
puts "Reload Metadata\n"
server.metadata.reload
print_metadata(server)
puts "Delete Metadata"
metadatum = server.metadata.find {|metadataum| metadataum.key == 'environment'}
metadatum.destroy
puts "Reload Metadata"
server.metadata.reload
print_metadata(server)
puts "To delete the server please execute the delete_server.rb script\n\n"

Просмотреть файл

@ -0,0 +1,60 @@
#!/usr/bin/env ruby
# This example demonstrates claiming messages with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
def select_queue(queues)
abort "\nThere are not any queues the Chicago region. Try running create_queue.rb\n\n" if queues.empty?
puts "\nSelect Queue To Delete:\n\n"
queues.each_with_index do |queue, i|
puts "\t #{i}. #{queue.name}"
end
delete_str = get_user_input "\nEnter Queue Number"
queues[delete_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Queue Service
service = Fog::Rackspace::Queues.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# retrieve list of queues
queues = service.queues
# prompt for queue
queue = select_queue(queues)
# prompt for number of messages to claim
num_claims = get_user_input "Enter Number of Messages to Claim"
# Claim messages
claim = queue.claims.create :ttl => 300, :grace => 100, :limit => num_claims
puts "The following messages have been claimed for the next 5 minutes [#{claim.id}]"
claim.messages.each do |message|
puts "\t[#{message.id}] #{message.body[0..50]}"
end

Просмотреть файл

@ -0,0 +1,45 @@
#!/usr/bin/env ruby
# This example demonstrates creating a queue with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Queue Service
service = Fog::Rackspace::Queues.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
#prompt for queue name
queue_name = get_user_input "Enter name for queue"
begin
# create queue
queue = service.queues.create :name => queue_name
puts "Queue #{queue_name} was successfully created"
puts "To delete the queue please execute the delete_queue.rb script\n\n"
rescue Fog::Rackspace::Queues::ServiceError => e
if e.status_code == 204
puts "Queue #{queue_name} already exists"
end
end

Просмотреть файл

@ -0,0 +1,71 @@
#!/usr/bin/env ruby
# This example demonstrates deleting a message with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
def select_queue(queues)
abort "\nThere are not any queues in the Chicago region. Try running create_queue.rb\n\n" if queues.empty?
puts "\nSelect Queue To Delete:\n\n"
queues.each_with_index do |queue, i|
puts "\t #{i}. #{queue.name}"
end
delete_str = get_user_input "\nEnter Queue Number"
queues[delete_str.to_i]
end
def select_message(messages)
abort "\nThere are not any messages in the Chicago region. Try running post_message.rb\n\n" if messages.empty?
puts "\nSelect Message To Delete:\n\n"
messages.each_with_index do |message, i|
puts "\t #{i}. [#{message.id}] #{message.body[0..50]}"
end
delete_str = get_user_input "\nEnter Message Number"
messages[delete_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Queue Service
service = Fog::Rackspace::Queues.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# retrieve list of queues
queues = service.queues
# prompt for queue
queue = select_queue(queues)
#retrieve list of messages
messages = queue.messages
# prompt for message
message = select_message(messages)
# delete message
message.destroy
puts "\nMessage #{message.id} has been destroyed\n"

Просмотреть файл

@ -0,0 +1,53 @@
#!/usr/bin/env ruby
# This example demonstrates deleting a queue with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
def select_queue(queues)
abort "\nThere are not any queues to delete in the Chicago region. Try running create_queue.rb\n\n" if queues.empty?
puts "\nSelect Queue To Delete:\n\n"
queues.each_with_index do |queue, i|
puts "\t #{i}. #{queue.name}"
end
delete_str = get_user_input "\nEnter Queue Number"
queues[delete_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Queue Service
service = Fog::Rackspace::Queues.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# retrieve list of queues
queues = service.queues
# prompt for queue to delete
queue = select_queue(queues)
# delete queue
queue.destroy
puts "\nQueue #{queue.name} has been destroyed\n"

Просмотреть файл

@ -0,0 +1,64 @@
#!/usr/bin/env ruby
# This example demonstrates listing messages in a queue with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
def get_user_boolean(prompt)
str = get_user_input(prompt)
return false unless str
str.match(/y(es)?/i) ? true : false
end
def select_queue(queues)
abort "\nThere are not any queues to post a message to in the Chicago region. Try running create_queue.rb\n\n" if queues.empty?
puts "\nSelect Queue:\n\n"
queues.each_with_index do |queue, i|
puts "\t #{i}. #{queue.name}"
end
delete_str = get_user_input "\nEnter Queue Number"
queues[delete_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Queue Service
service = Fog::Rackspace::Queues.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# retrieve list of queues
queues = service.queues
# prompt for queue to delete
queue = select_queue(queues)
queue.messages.echo = get_user_boolean "Do you want to include your own messages? [y/N]"
queue.messages.include_claimed = get_user_boolean "Do you want to include claimed messages? [y/N]"
puts "\n\nThe following messages are in the '#{queue.name}' queue:\n\n"
queue.messages.each do |message|
puts message.inspect
end

Просмотреть файл

@ -0,0 +1,59 @@
#!/usr/bin/env ruby
# This example demonstrates posting a message to a queue with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
def select_queue(queues)
abort "\nThere are not any queues to post a message to in the Chicago region. Try running create_queue.rb\n\n" if queues.empty?
puts "\nSelect Queue:\n\n"
queues.each_with_index do |queue, i|
puts "\t #{i}. #{queue.name}"
end
delete_str = get_user_input "\nEnter Queue Number"
queues[delete_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Queue Service
service = Fog::Rackspace::Queues.new({
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# retrieve list of queues
queues = service.queues
# prompt for queue to delete
queue = select_queue(queues)
# prompt for queue message
message = get_user_input "Enter Queue Message"
# time to live TTL = 1 hour
ttl = 3600
# post message to queue
queue.messages.create :body => message, :ttl => ttl
puts "The message has been successfully posted"

Просмотреть файл

@ -0,0 +1,43 @@
#!/usr/bin/env ruby
# This example demonstrates creating a container with CDN on the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Cloud Files service
service = Fog::Storage.new({
:provider => 'Rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# prompt for directory name
directory_name = get_user_input "\nEnter name of directory to create"
# create directory
directory = service.directories.create :key => directory_name, :public => true
# reload directory to refresh information
directory.reload
puts "\nDirectory #{directory.key} was created."
puts "To delete the container please execute the delete_directory.rb script\n\n"

Просмотреть файл

@ -0,0 +1,43 @@
#!/usr/bin/env ruby
# This example demonstrates creating a container with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Cloud Files service
service = Fog::Storage.new({
:provider => 'Rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# prompt for directory name
directory_name = get_user_input "\nEnter name of directory to create"
# create directory
directory = service.directories.create :key => directory_name
# reload directory to refresh information
directory.reload
puts "\n Directory #{directory.key} was created."
puts "To delete the container please execute the delete_directory.rb script\n\n"

Просмотреть файл

@ -0,0 +1,62 @@
#!/usr/bin/env ruby
# This example demonstrates deleting a container with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
def select_directory(directories)
abort "\nThere are not any directories to delete in the Chicago region. Try running create_directory.rb\n\n" if directories.empty?
puts "\nSelect Directory To Delete:\n\n"
directories.each_with_index do |dir, i|
puts "\t #{i}. #{dir.key} [#{dir.count} objects]"
end
delete_str = get_user_input "\nEnter Directory Number"
directories[delete_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Cloud Files service
service = Fog::Storage.new({
:provider => 'Rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# retrieve directories
directories = service.directories
# prompt for directory
directory = select_directory(directories)
puts "\nNow deleting #{directory.key}"
# delete files if necessary
directory.files.each do |f|
puts "\tDeleting file #{f.key}"
f.destroy
end
# delete directory
directory.destroy
puts "\tDone\n\n"

Просмотреть файл

@ -0,0 +1,70 @@
#!/usr/bin/env ruby
# This example demonstrates deleting a file from a container with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
def select_directory(directories)
abort "\nThere are not any directories with files to delete in the Chicago region. Try running create_file.rb\n\n" if directories.empty?
puts "\nSelect Directory:\n\n"
directories.each_with_index do |dir, i|
puts "\t #{i}. #{dir.key} [#{dir.count} objects]"
end
delete_str = get_user_input "\nEnter Directory Number"
directories[delete_str.to_i]
end
def select_file(files)
puts "\nSelect File:\n\n"
files.each_with_index do |file, i|
puts "\t #{i}. #{file.key}"
end
delete_str = get_user_input "\nEnter File Number"
files[delete_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Cloud Files service
service = Fog::Storage.new({
:provider => 'Rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# retrieve directories with files
directories = service.directories.select {|s| s.count > 0}
# prompt for directory
directory = select_directory(directories)
# list of files for directory
files = directory.files
# prompt for file to delete
file = select_file(files)
# delete file
file.destroy
puts "\nFile #{file.key} was successfully deleted"

Просмотреть файл

@ -0,0 +1,75 @@
#!/usr/bin/env ruby
# This example demonstrates downloading a file with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
def select_directory(directories)
abort "\nThere are not any directories with files in the Chicago region. Try running create_file.rb\n\n" if directories.empty?
puts "\nSelect Directory:\n\n"
directories.each_with_index do |dir, i|
puts "\t #{i}. #{dir.key} [#{dir.count} objects]"
end
delete_str = get_user_input "\nEnter Directory Number"
directories[delete_str.to_i]
end
def select_file(files)
puts "\nSelect File:\n\n"
files.each_with_index do |file, i|
puts "\t #{i}. #{file.key}"
end
delete_str = get_user_input "\nEnter File Number"
files[delete_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Cloud Files service
service = Fog::Storage.new({
:provider => 'Rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# retrieve directories with files
directories = service.directories.select {|s| s.count > 0}
# prompt for directory
directory = select_directory(directories)
# list of files for directory
files = directory.files
# prompt for file to download
file = select_file(files)
# download file
filename = File.join(File.dirname(__FILE__), "downloaded-#{file.key}")
File.open(filename, 'w') do | f |
directory.files.get(file.key) do | data, remaining, content_length |
f.syswrite data
end
end
puts "\nFile #{file.key} was successfully downloaded to #{filename}"

Просмотреть файл

@ -0,0 +1 @@
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Просмотреть файл

@ -0,0 +1,76 @@
#!/usr/bin/env ruby
# This example demonstrates creating a file on the CDN network with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
def print_metadata(object)
object.metadata.each_pair do |key, value|
puts "\t#{key}: #{value}"
end
puts "\n"
end
# create Cloud Files service
service = Fog::Storage.new({
:provider => 'Rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# create directory
puts "Creating directory 'metadata-tester'"
directory = service.directories.create :key => "metadata-tester"
# initial metadata
puts "Initial Container Metadata\n"
print_metadata directory
# adding metadata
puts "Adding Container Metadata"
directory.metadata["environment"] = "demo"
directory.save
print_metadata directory
# update metadata
puts "Updating Container Metadata"
directory.metadata["environment"] = "test"
directory.save
print_metadata directory
# upload file
puts "Uploading file"
upload_file = File.join(File.dirname(__FILE__), "lorem.txt")
file = directory.files.create :key => 'sample.txt', :body => File.open(upload_file, "r")
# initial metadata
puts "Initial File Metadata\n"
print_metadata file
# adding metadata
puts "Adding File Metadata"
file.metadata["preview"] = "true"
file.save
print_metadata file
# update metadata
puts "Updating File Metadata"
file.metadata["preview"] = "false"
file.save
print_metadata file
puts "To delete the directory and file please execute the delete_directory.rb script\n\n"

Просмотреть файл

@ -0,0 +1,44 @@
#!/usr/bin/env ruby
# This example demonstrates creating a file on the CDN network with the Rackpace Open Cloud
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
def get_user_input(prompt)
print "#{prompt}: "
gets.chomp
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Cloud Files service
service = Fog::Storage.new({
:provider => 'Rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord #Use Chicago Region
})
# prompt for directory name
directory_name = get_user_input "\nEnter name of directory to create"
# create directory with CDN service
directory = service.directories.create :key => directory_name, :public => true
# upload file
upload_file = File.join(File.dirname(__FILE__), "lorem.txt")
file = directory.files.create :key => 'sample.txt', :body => File.open(upload_file, "r")
puts "You should be able to view this file via CDN at #{file.public_url}"
puts "To delete the container and associated file please execute the delete_directory.rb script\n\n"

Просмотреть файл

@ -0,0 +1,101 @@
#!/usr/bin/env ruby
# This example demonstrates uploading large files in segments
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
# Size of segment. The Rackspace cloud currently requires files larger than 5GB to be segmented so we will choose 5GB -1 for a size
# http://docs.rackspace.com/files/api/v1/cf-devguide/content/Large_Object_Creation-d1e2019.html
SEGMENT_LIMIT = 5368709119.0
# Size of buffer to use for transfers. Use Excon's default chunk size and if that's not avaliable we will default to 1 MB
BUFFER_SIZE = Excon.defaults[:chunk_size] || 1024 * 1024
def get_user_input(prompt)
print "\n#{prompt}: "
gets.chomp
end
def select_directory(directories)
abort "\nThere are not any directories in the Chicago region. Try running create_private_directory.rb\n\n" if directories.empty?
puts "\nSelect Directory:\n\n"
directories.each_with_index do |dir, i|
puts "\t #{i}. #{dir.key} [#{dir.count} objects]"
end
select_str = get_user_input "Enter Directory Number"
directories[select_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Cloud Files service
service = Fog::Storage.new({
:provider => 'Rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord
})
# retrieve directories with files
directories = service.directories
# prompt for directory
directory = select_directory(directories)
# prompt for file name
file_name = get_user_input "Enter full path of file to upload"
segment_name = File.basename(file_name)
File.open(file_name) do |f|
num_segments = (f.stat.size / SEGMENT_LIMIT).round + 1
puts "\nThis upload of '#{file_name}' will require #{num_segments} segment(s) and 1 manifest file\n"
segment = 0
until f.eof?
segment += 1
offset = 0
# upload segment to cloud files
segment_suffix = segment.to_s.rjust(10, '0')
print "\n\tUploading segment #{segment_suffix} "
service.put_object(directory.key, "#{segment_name}/#{segment_suffix}", nil) do
if offset <= SEGMENT_LIMIT - BUFFER_SIZE
print "."
buf = f.read(BUFFER_SIZE).to_s
offset += buf.size
buf
else
''
end
end
end
end
puts "\n\n\tWriting manifest #{segment_name}\n\n"
service.put_object_manifest(directory.key, segment_name, 'X-Object-Manifest' => "#{directory.key}/#{segment_name}/" )
puts <<-NOTE
You should now be able to download #{segment_name} from the cloud control panel or using the following code:
directory = service.directories.get('#{directory.key}')
File.open('downloaded_#{segment_name}', 'w') do | f |
directory.files.get('#{segment_name}') do | data, remaining, content_length |
print "."
f.write data
end
end
NOTE

Просмотреть файл

@ -0,0 +1,83 @@
require 'fog/rackspace/core'
module Fog
module Rackspace
class Identity < Fog::Service
US_ENDPOINT = 'https://identity.api.rackspacecloud.com/v2.0'
UK_ENDPOINT = 'https://lon.identity.api.rackspacecloud.com/v2.0'
requires :rackspace_username, :rackspace_api_key
recognizes :rackspace_auth_url, :rackspace_region
model_path 'fog/rackspace/models/identity'
model :user
collection :users
model :role
collection :roles
model :credential
collection :credentials
model :tenant
collection :tenants
model :service_catalog
request_path 'fog/rackspace/requests/identity'
request :create_token
request :list_users
request :list_user_roles
request :list_credentials
request :list_tenants
request :get_user_by_id
request :get_user_by_name
request :create_user
request :update_user
request :delete_user
module Common
attr_reader :service_catalog, :auth_token
def authenticate(options={})
data = self.create_token(@rackspace_username, @rackspace_api_key).body
@service_catalog = ServiceCatalog.from_response(self, data)
@auth_token = data['access']['token']['id']
end
def apply_options(options)
@rackspace_username = options[:rackspace_username]
@rackspace_api_key = options[:rackspace_api_key]
@rackspace_region = options[:rackspace_region]
@rackspace_auth_url = options[:rackspace_auth_url] || US_ENDPOINT
@uri = URI.parse(@rackspace_auth_url)
@host = @uri.host
@path = @uri.path
@port = @uri.port
@scheme = @uri.scheme
@persistent = options[:persistent] || false
@connection_options = options[:connection_options] || {}
end
end
class Mock < Fog::Rackspace::Service
include Common
def initialize(options={})
apply_options(options)
authenticate
end
end
class Real < Fog::Rackspace::Service
include Common
def initialize(options={})
apply_options(options)
@connection = Fog::Core::Connection.new(@uri.to_s, @persistent, @connection_options)
authenticate
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,206 @@
require 'fog/rackspace/core'
module Fog
module Rackspace
class LoadBalancers < Fog::Service
include Fog::Rackspace::Errors
#These references exist for backwards compatibility
class ServiceError < Fog::Rackspace::Errors::ServiceError; end
class InternalServerError < Fog::Rackspace::Errors::InternalServerError; end
class BadRequest < Fog::Rackspace::Errors::BadRequest; end
DFW_ENDPOINT = 'https://dfw.loadbalancers.api.rackspacecloud.com/v1.0'
ORD_ENDPOINT = 'https://ord.loadbalancers.api.rackspacecloud.com/v1.0'
LON_ENDPOINT = 'https://lon.loadbalancers.api.rackspacecloud.com/v1.0'
requires :rackspace_api_key, :rackspace_username
recognizes :rackspace_auth_url
recognizes :rackspace_auth_token
recognizes :rackspace_lb_endpoint
recognizes :rackspace_load_balancers_url
recognizes :rackspace_region
model_path 'fog/rackspace/models/load_balancers'
collection :load_balancers
model :load_balancer
collection :nodes
model :node
collection :virtual_ips
model :virtual_ip
collection :access_rules
model :access_rule
request_path 'fog/rackspace/requests/load_balancers'
request :get_ssl_termination
request :set_ssl_termination
request :remove_ssl_termination
request :create_load_balancer
request :get_load_balancer
request :list_load_balancers
request :update_load_balancer
request :delete_load_balancer
request :create_node
request :list_nodes
request :get_node
request :update_node
request :delete_node
request :delete_nodes
request :create_virtual_ip
request :list_virtual_ips
request :delete_virtual_ip
request :list_protocols
request :list_algorithms
request :get_connection_logging
request :set_connection_logging
request :get_content_caching
request :set_content_caching
request :create_access_rule
request :list_access_rules
request :delete_access_rule
request :delete_all_access_rules
request :get_session_persistence
request :set_session_persistence
request :remove_session_persistence
request :get_connection_throttling
request :remove_connection_throttling
request :set_connection_throttling
request :get_monitor
request :set_monitor
request :remove_monitor
request :get_usage
request :get_load_balancer_usage
request :get_error_page
request :set_error_page
request :remove_error_page
request :get_stats
module Shared
def algorithms
list_algorithms.body['algorithms'].map { |i| i['name'] }
end
def protocols
list_protocols.body['protocols']
end
def usage(options = {})
get_usage(options).body
end
end
class Mock < Fog::Rackspace::Service
include Shared
def initialize(options={})
@rackspace_api_key = options[:rackspace_api_key]
@rackspace_username = options[:rackspace_username]
@rackspace_auth_url = options[:rackspace_auth_url]
end
end
class Real < Fog::Rackspace::Service
include Shared
def initialize(options={})
@rackspace_api_key = options[:rackspace_api_key]
@rackspace_username = options[:rackspace_username]
@rackspace_auth_url = options[:rackspace_auth_url]
@rackspace_must_reauthenticate = false
@connection_options = options[:connection_options] || {}
setup_custom_endpoint(options)
authenticate
deprecation_warnings(options)
@persistent = options[:persistent] || false
@connection = Fog::Core::Connection.new(endpoint_uri.to_s, @persistent, @connection_options)
end
def request(params, parse_json = true)
super
rescue Excon::Errors::NotFound => error
raise NotFound.slurp(error, self)
rescue Excon::Errors::BadRequest => error
raise BadRequest.slurp(error, self)
rescue Excon::Errors::InternalServerError => error
raise InternalServerError.slurp(error, self)
rescue Excon::Errors::HTTPStatusError => error
raise ServiceError.slurp(error, self)
end
def authenticate(options={})
super({
:rackspace_api_key => @rackspace_api_key,
:rackspace_username => @rackspace_username,
:rackspace_auth_url => @rackspace_auth_url,
:connection_options => @connection_options
})
end
def service_name
:cloudLoadBalancers
end
def region
@rackspace_region
end
def endpoint_uri(service_endpoint_url=nil)
@uri = super(@rackspace_endpoint || service_endpoint_url, :rackspace_load_balancers_url)
end
private
def setup_custom_endpoint(options)
@rackspace_endpoint = Fog::Rackspace.normalize_url(options[:rackspace_load_balancers_url] || options[:rackspace_lb_endpoint])
if v2_authentication?
case @rackspace_endpoint
when DFW_ENDPOINT
@rackspace_endpoint = nil
@rackspace_region = :dfw
when ORD_ENDPOINT
@rackspace_endpoint = nil
@rackspace_region = :ord
when LON_ENDPOINT
@rackspace_endpoint = nil
@rackspace_region = :lon
else
# we are actually using a custom endpoint
@rackspace_region = options[:rackspace_region]
end
else
#if we are using auth1 and the endpoint is not set, default to DFW_ENDPOINT for historical reasons
@rackspace_endpoint ||= DFW_ENDPOINT
end
end
def deprecation_warnings(options)
Fog::Logger.deprecation("The :rackspace_lb_endpoint option is deprecated. Please use :rackspace_load_balancers_url for custom endpoints") if options[:rackspace_lb_endpoint]
if [DFW_ENDPOINT, ORD_ENDPOINT, LON_ENDPOINT].include?(@rackspace_endpoint) && v2_authentication?
regions = @identity_service.service_catalog.display_service_regions(service_name)
Fog::Logger.deprecation("Please specify region using :rackspace_region rather than :rackspace_endpoint. Valid regions for :rackspace_region are #{regions}.")
end
end
def append_tenant_v1(credentials)
account_id = credentials['X-Server-Management-Url'].match(/.*\/([\d]+)$/)[1]
endpoint = @rackspace_endpoint || credentials['X-Server-Management-Url'] || DFW_ENDPOINT
@uri = URI.parse(endpoint)
@uri.path = "#{@uri.path}/#{account_id}"
end
def authenticate_v1(options)
credentials = Fog::Rackspace.authenticate(options, @connection_options)
append_tenant_v1 credentials
@auth_token = credentials['X-Auth-Token']
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,252 @@
module Fog
module Rackspace
module MockData
NOT_FOUND_ID = "NOT-FOUND"
def data
@@data ||= Hash.new do |hash, key|
hash[key] = begin
#Compute V2
flavor_id = Fog.credentials[:rackspace_flavor_id] ||= '3'
image_id = Fog.credentials[:rackspace_image_id] ||= Fog::Rackspace::MockData.uuid
image_name = Fog::Mock.random_letters(6)
network_id = Fog::Rackspace::MockData.uuid
user_id = Fog::Mock.random_numbers(6).to_s
flavor = {
"OS-FLV-EXT-DATA:ephemeral" => 4,
"disk" => 20,
"id" => flavor_id,
"links" => [
{
"href" => "https://dfw.servers.api.rackspacecloud.com/v2/010101/flavors/#{flavor_id}",
"rel" => "self"
},
{
"href" => "https://dfw.servers.api.rackspacecloud.com/010101/flavors/#{flavor_id}",
"rel" => "bookmark"
}
],
"name" => "512MB Standard Instance",
"ram" => 512,
"rxtx_factor" => 2.0,
"swap" => 512,
"vcpus" => 1,
}
image = {
"OS-DCF:diskConfig" => "AUTO",
"created" => "2012-02-28T19:38:57Z",
"id" => image_id,
"name" => image_name,
"links" => [
{
"href" => "https://dfw.servers.api.rackspacecloud.com/v2/010101/images/#{image_id}",
"rel" => "self"
},
{
"href" => "https://dfw.servers.api.rackspacecloud.com/010101/images/#{image_id}",
"rel" => "bookmark"
},
{
"href" => "https://dfw.servers.api.rackspacecloud.com/010101/images/#{image_id}",
"rel" => "alternate",
"type" => "application/vnd.openstack.image"
}
],
"metadata" => {
"arch" => "x86-64",
"auto_disk_config" => "True",
"com.rackspace__1__build_core" => "1",
"com.rackspace__1__build_managed" => "0",
"com.rackspace__1__build_rackconnect" => "0",
"com.rackspace__1__options" => "0",
"com.rackspace__1__visible_core" => "1",
"com.rackspace__1__visible_managed" => "0",
"com.rackspace__1__visible_rackconnect" => "0",
"image_type" => "base",
"org.openstack__1__architecture" => "x64",
"org.openstack__1__os_distro" => "org.ubuntu",
"org.openstack__1__os_version" => "11.10",
"os_distro" => "ubuntu",
"os_type" => "linux",
"os_version" => "11.10",
"rax_managed" => "false",
"rax_options" => "0"
},
"minDisk" => 10,
"minRam" => 256,
"progress" => 100,
"status" => "ACTIVE",
"updated" => "2012-02-28T19:39:05Z"
}
network = {
'id' => network_id,
'label' => 'network label',
'cidr' => '192.168.0.0/24'
}
key_pair = {
'public_key' => "ssh-rsa ".concat(Fog::Mock.random_letters(372)).concat(" Generated by Nova\n"),
'private_key' => "-----BEGIN RSA PRIVATE KEY-----\n".concat(Fog::Mock.random_letters(1635)).concat("\n-----END RSA PRIVATE KEY-----\n"),
'user_id' => user_id,
'name' => Fog::Mock.random_letters(32),
'fingerprint' => "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"
}
#Block Storage
volume_type1_id = Fog::Mock.random_numbers(3).to_s
volume_type2_id = Fog::Mock.random_numbers(3).to_s
volume_type1 = {
"id" => volume_type1_id,
"name" => "SATA",
"extra_specs" => {},
}
volume_type2 = {
"id" => volume_type2_id,
"name" => "SSD",
"extra_specs" => {},
}
#AutoScale
launch_config = {
"args" => {
"loadBalancers" => [
{
"port" => 8080,
"loadBalancerId" => 9099
}
],
"server" => {
"name" => "autoscale_server",
"imageRef" => "0d589460-f177-4b0f-81c1-8ab8903ac7d8",
"flavorRef" => "2",
"OS-DCF =>diskConfig" => "AUTO",
"metadata" => {
"build_config" => "core",
"meta_key_1" => "meta_value_1",
"meta_key_2" => "meta_value_2"
},
"networks" => [
{
"uuid" => "11111111-1111-1111-1111-111111111111"
},
{
"uuid" => "00000000-0000-0000-0000-000000000000"
}
],
"personality" => [
{
"path" => "/root/.csivh",
"contents" => "VGhpcyBpcyBhIHRlc3QgZmlsZS4="
}
]
}
},
"type" => "launch_server"
}
group_config = {
"max_entities" => 10,
"cooldown" => 360,
"name" => "testscalinggroup198547",
"min_entities" => 0,
"metadata" => {
"gc_meta_key_2" => "gc_meta_value_2",
"gc_meta_key_1" => "gc_meta_value_1"
}
}
policy = {
"cooldown" => 0,
"type" => "webhook",
"name" => "scale up by 1",
"change" => 1
}
webhook = {
"name" => "webhook name",
"metadata" => {'foo' => 'bar'}
}
mock_data = {
#Compute V2
:flavors => Hash.new { |h,k| h[k] = flavor unless [NOT_FOUND_ID, '0'].include?(k) },
:images => Hash.new { |h,k| h[k] = image unless [NOT_FOUND_ID, '0'].include?(k) },
:networks => Hash.new { |h,k| h[k] = network unless [NOT_FOUND_ID, '0'].include?(k) },
:keys => [],
:keypair => key_pair,
:keypairs => [],
:servers => {},
#Block Storage
:volumes => {},
:snapshots => {},
:volume_attachments => [],
:volume_types => {volume_type1_id => volume_type1, volume_type2_id => volume_type2},
#Autoscale
:autoscale_groups => {}
}
# seed with initial data
mock_data[:flavors][flavor_id] = flavor
mock_data[:images][image_id] = image
mock_data[:networks][network_id] = network
mock_data
end
end[@rackspace_api_key]
end
def self.uuid
[8,4,4,4,12].map{|i| Fog::Mock.random_hex(i)}.join("-")
end
def self.ipv4_address
4.times.map{ Fog::Mock.random_numbers(3) }.join(".")
end
def self.ipv6_address
8.times.map { Fog::Mock.random_hex(4) }.join(":")
end
def self.keep(hash, *keys)
{}.tap do |kept|
keys.each{|k| kept[k]= hash[k] if hash.key?(k)}
end
end
def self.slice(hash, *keys)
hash.dup.tap do |sliced|
keys.each{|k| sliced.delete(k)}
end
end
def self.zulu_time
Time.now.strftime("%Y-%m-%dT%H:%M:%SZ")
end
def self.stringify(message)
case message
when Symbol
message.to_s
when Hash
result = Hash.new
message.each do |key, value|
nk = stringify(key)
nv = stringify(value)
result[nk] = nv
end
result
else
message
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,214 @@
require 'fog/core/model'
require 'fog/rackspace/models/auto_scale/group_config'
require 'fog/rackspace/models/auto_scale/launch_config'
require 'fog/rackspace/models/auto_scale/policies'
module Fog
module Rackspace
class AutoScale
class Group < Fog::Model
# @!attribute [r] id
# @return [String] The autoscale group's id
identity :id
# @!attribute [r] links
# @return [Array] group links.
attribute :links
# Gets the group configuration for this autoscale group. The configuration describes the
# minimum number of entities in the group, the maximum number of entities in the group,
# the global cooldown time for the group, and other metadata.
#
# @return [Fog::Rackspace::AutoScale::GroupConfiguration] group_config if found
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/GET_getGroupConfig_v1.0__tenantId__groups__groupId__config_Configurations.html
def group_config
if attributes[:group_config].nil? && persisted?
data = service.get_group_config(identity)
attributes[:group_config] = load_model('GroupConfig', data.body['groupConfiguration'])
end
attributes[:group_config]
end
# Sets the configuration when this object is populated.
#
# @param object [Hash<String, String>] Object which will stock the object
def group_config=(object = {})
if object.is_a?(Hash)
attributes[:group_config] = load_model('GroupConfig', object)
else
attributes[:group_config] = object
end
end
# Gets the launch configuration for this autoscale group. The launch configuration describes
# the details of how to create a server, from what image to create a server, which load balancers
# to join the server to, which networks to add the server to, and other metadata.
#
# @return [Fog::Rackspace::AutoScale::LaunchConfiguration] group_config if found
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/GET_getLaunchConfig_v1.0__tenantId__groups__groupId__launch_Configurations.html
def launch_config
if attributes[:launch_config].nil? && persisted?
data = service.get_launch_config(identity)
attributes[:launch_config] = load_model('LaunchConfig', data.body['launchConfiguration'])
end
attributes[:launch_config]
end
# Sets the configuration when this object is populated.
#
# @param object [Hash<String, String>] Object which will stock the object
def launch_config=(object={})
if object.is_a?(Hash)
attributes[:launch_config] = load_model('LaunchConfig', object)
else
attributes[:launch_config] = object
end
end
# For the specified autoscaling group, this operation returns a list of the scaling policies
# that are available to the group. Each policy is described in terms of an ID, name, type,
# adjustment, cooldown time, and links.
#
# @return [Fog::Rackspace::AutoScale::Policies] policies
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/GET_getPolicies_v1.0__tenantId__groups__groupId__policies_Policies.html
def policies
return @policies if @policies
if persisted?
@policies = load_model('Policies')
else
@policies = Fog::Rackspace::AutoScale::Policies.new(:service => service, :group => self)
@policies.clear
end
@policies
# return nil unless persisted?
# @policies ||= load_model('Policies')
end
# Creates group
# * requires attributes: :launch_config, :group_config, :policies
#
# @return [Boolean] returns true if group is being created
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see Groups#create
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/POST_createGroup_v1.0__tenantId__groups_Groups.html
def save
requires :launch_config, :group_config, :policies
raise Fog::Errors::Error.new("You should update launch_config and group_config directly") if persisted?
launch_config_hash = {
'args' => launch_config.args,
'type' => launch_config.type
}
group_config_hash = {
'name' => group_config.name,
'cooldown' => group_config.cooldown,
'maxEntities' => group_config.max_entities,
'minEntities' => group_config.min_entities
}
group_config_hash['metadata'] = group_config.metadata if group_config.metadata
data = service.create_group(launch_config_hash, group_config_hash, policies)
merge_attributes(data.body['group'])
true
end
# Destroy the group
#
# @return [Boolean] returns true if group has started deleting
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/DELETE_deleteGroup_v1.0__tenantId__groups__groupId__Groups.html
def destroy
requires :identity
service.delete_group(identity)
true
end
# Get the current state of the autoscale group
#
# @return [String] the state of the group
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/GET_getGroupState_v1.0__tenantId__groups__groupId__state_Groups.html
def state
requires :identity
data = service.get_group_state(identity)
data.body['group']
end
# This operation pauses all execution of autoscaling policies.
#
# @note NOT IMPLEMENTED YET
# @return [Boolean] returns true if paused
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/POST_pauseGroup_v1.0__tenantId__groups__groupId__pause_Groups.html
def pause
requires :identity
data = service.pause_group_state(identity)
true
end
# This operation resumes all execution of autoscaling policies.
#
# @note NOT IMPLEMENTED YET
# @return [Boolean] returns true if resumed
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/POST_resumeGroup_v1.0__tenantId__groups__groupId__resume_Groups.html
def resume
requires :identity
data = service.resume_group_state(identity)
true
end
private
def load_model(class_name, attrs = nil)
model = Fog::Rackspace::AutoScale.const_get(class_name).new({
:service => @service,
:group => self
})
if service && attrs
model.merge_attributes(attrs)
end
model
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,86 @@
require 'fog/core/model'
require 'fog/rackspace/models/auto_scale/group_config'
require 'fog/rackspace/models/auto_scale/launch_config'
require 'fog/rackspace/models/auto_scale/policies'
module Fog
module Rackspace
class AutoScale
class GroupBuilder
class << self
def build(service, attributes)
service.groups.new :group_config => build_group_config(attributes), :launch_config => build_server_launch_config(attributes)
end
def build_group_config(attributes)
Fog::Rackspace::AutoScale::GroupConfig.new :max_entities => attributes[:max_entities],
:min_entities => attributes[:min_entities],
:cooldown => attributes[:cooldown],
:name => attributes[:name],
:metadata => attributes[:metadata] || {}
end
def build_server_launch_config(attributes)
return nil unless attributes[:launch_config_type] == :launch_server
args = {"server" => build_server_template(attributes) }
args["loadBalancers"] = build_load_balancers(attributes) if attributes[:load_balancers]
Fog::Rackspace::AutoScale::LaunchConfig.new :type => :launch_server, :args => args
end
private
def build_load_balancers(attributes)
return nil unless attributes[:load_balancers]
load_balancers = attributes[:load_balancers].is_a?(Array) ? attributes[:load_balancers] : [attributes[:load_balancers]]
load_balancers.map do |obj|
obj.is_a?(Hash) ? obj : load_balancer_to_hash(obj)
end
end
def load_balancer_to_hash(lb)
raise ArgumentError.new("Expected LoadBalancer") unless lb.respond_to?(:id) && lb.respond_to?(:port)
{
"port" => lb.port,
"loadBalancerId" => lb.id
}
end
def build_server_template(attributes)
image_id = get_id(:image, attributes)
flavor_id = get_id(:flavor, attributes)
server_template = {
"name" => attributes[:server_name],
"imageRef" => image_id,
"flavorRef" => flavor_id,
"OS-DCF =>diskConfig" => attributes[:disk_config] || "MANUAL",
"metadata" => attributes[:server_metadata] || {}
}
server_template["personality"] = attributes[:personality] if attributes[:personality]
server_template["user_data"] = [attributes[:user_data]].pack('m') if attributes[:user_data]
server_template["config_drive"] = 'true' if attributes[:config_drive]
server_template["networks"] = networks_to_hash(attributes[:networks]) if attributes[:networks]
server_template
end
def model?(obj)
obj.class.ancestors.include?(Fog::Model)
end
def get_id(type, attributes)
id = attributes["#{type}_id".to_sym]
type_key = type.to_sym
id ||= model?(attributes[type_key]) ? attributes[type_key].id : attributes[type_key]
end
def networks_to_hash(networks)
networks.map {|n| {"uuid" => n}}
end
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,76 @@
require 'fog/core/model'
module Fog
module Rackspace
class AutoScale
class GroupConfig < Fog::Model
# @!attribute [r] group
# @return [Fog::Rackspace::AutoScale::Group] The parent group
attribute :group
# @!attribute [r] name
# @return [String] The name of the group
attribute :name
# @!attribute [r] cooldown
# @return [String] The group's cooldown
attribute :cooldown
# @!attribute [r] min_entities
# @return [Fixnum] The minimum amount of units which should exist in the group
attribute :min_entities, :aliases => 'minEntities'
# @!attribute [r] max_entities
# @return [Fixnum] The maximum amount of units which should exist in the group
attribute :max_entities, :aliases => 'maxEntities'
# @!attribute [r] metadata
# @return [Hash] The group's metadata
attribute :metadata
# Update this group's configuration
#
# @return [Boolean] returns true if group config has been updated
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/PUT_putGroupConfig_v1.0__tenantId__groups__groupId__config_Configurations.html
def update
options = {}
options['name'] = name unless name.nil?
options['cooldown'] = cooldown unless cooldown.nil?
options['minEntities'] = min_entities
options['maxEntities'] = max_entities
options['metadata'] = metadata unless metadata.nil?
service.update_group_config(group.id, options)
true
end
# Saves group configuration.
# This method will only save existing group configurations. New group configurations are created when a scaling group is created
#
# @return [Boolean] true if group config was saved
def save
if group.id
update
true
else
raise "New #{self.class} are created when a new Fog::Rackspace::AutoScale::Group is created"
end
end
# Reloads group configuration
def reload
if group.id
data = service.get_group_config(group.id)
merge_attributes data.body['groupConfiguration']
end
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,45 @@
require 'fog/core/collection'
require 'fog/rackspace/models/auto_scale/group'
module Fog
module Rackspace
class AutoScale
class Groups < Fog::Collection
model Fog::Rackspace::AutoScale::Group
# Returns list of autoscale groups
#
# @return [Fog::Rackspace::AutoScale::Groups] Retrieves a list groups.
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/GET_getGroups_v1.0__tenantId__groups_Groups.html
def all
data = service.list_groups.body['groups']
load(data)
end
# Returns an individual autoscale group
#
# @return [Fog::Rackspace::AutoScale::Group] Retrieves a list groups.
# @return nil if not found
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/GET_getGroupManifest_v1.0__tenantId__groups__groupId__Groups.html
def get(group_id)
data = service.get_group(group_id).body['group']
new(data)
rescue Fog::Rackspace::AutoScale::NotFound
nil
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,61 @@
require 'fog/core/model'
module Fog
module Rackspace
class AutoScale
class LaunchConfig < Fog::Model
# @!attribute [r] group
# @return [Fog::Rackspace::AutoScale::Group] The parent group
attribute :group
# @!attribute [r] type
# @return [Fog::Rackspace::AutoScale::Group] The type of operation (usually "launch_server")
attribute :type
# @!attribute [r] args
# @return [Fog::Rackspace::AutoScale::Group] The arguments for the operation
attribute :args
# Update this group's launch configuration
#
# @return [Boolean] returns true if launch config has been updated
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/PUT_putLaunchConfig_v1.0__tenantId__groups__groupId__launch_Configurations.html
def update
options = {}
options['type'] = type unless type.nil?
options['args'] = args unless args.nil?
service.update_launch_config(group.id, options)
true
end
# Saves group launch configuration.
# This method will only save existing group configurations. New group configurations are created when a scaling group is created
#
# @return [Boolean] true if launch group was saved
def save
if group.id
update
true
else
raise "New #{self.class} are created when a new Fog::Rackspace::AutoScale::Group is created"
end
end
# Reloads group launch configuration
def reload
if group.id
data = service.get_launch_config(group.id)
merge_attributes data.body['launchConfiguration']
end
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,65 @@
require 'fog/core/collection'
require 'fog/rackspace/models/auto_scale/policy'
module Fog
module Rackspace
class AutoScale
class Policies < Fog::Collection
model Fog::Rackspace::AutoScale::Policy
attr_accessor :group
# Returns list of autoscale policies
#
# @return [Fog::Rackspace::AutoScale::Policies] Retrieves policies
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/GET_getPolicies_v1.0__tenantId__groups__groupId__policies_Policies.html
def all
data = service.list_policies(group.id).body['policies']
load(data)
end
# Returns an individual autoscale policy
#
# @return [Fog::Rackspace::AutoScale::Group] Retrieves a policy
# @return nil if not found
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/GET_getPolicy_v1.0__tenantId__groups__groupId__policies__policyId__Policies.html
def get(policy_id)
data = service.get_policy(group.id, policy_id).body['policy']
new(data)
rescue Fog::Rackspace::AutoScale::NotFound
nil
end
# Create an autoscale policy
#
# @return [Fog::Rackspace::AutoScale::Policy] Returns the new policy
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/POST_createPolicies_v1.0__tenantId__groups__groupId__policies_Policies.html
def create(attributes = {})
super(attributes)
end
def new(attributes = {})
super({:group => group}.merge(attributes))
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,220 @@
require 'fog/core/model'
require 'fog/rackspace/models/auto_scale/webhooks'
module Fog
module Rackspace
class AutoScale
class Policy < Fog::Model
# @!attribute [r] id
# @return [String] The policy id
identity :id
# @!attribute [r] group
# @return [Group] The autoscale group
attribute :group
# @!attribute [r] links
# @return [Array] Policy links
attribute :links
# @!attribute [r] name
# @return [String] The policy's name
attribute :name
# @!attribute [r] change
# @return [Fixnum] The fixed change to the autoscale group's number of units
attribute :change
# @!attribute [r] changePercent
# @return [Fixnum] The percentage change to the autoscale group's number of units
attribute :change_percent, :aliases => 'changePercent'
# @!attribute [r] cooldown
# @return [Fixnum] The policy's cooldown
attribute :cooldown
# @!attribute [r] type
# @note Can only be "webhook", "schedule" or "cloud_monitoring"
# @return [String] The policy's type
attribute :type
# @!attribute [r] args
# @example See below:
# - "cron": "23 * * * *"
# - "at": "2013-06-05T03:12Z"
# - "check": {
# "label": "Website check 1",
# "type": "remote.http",
# "details": {
# "url": "http://www.example.com",
# "method": "GET"
# },
# "monitoring_zones_poll": [
# "mzA"
# ],
# "timeout": 30,
# "period": 100,
# "target_alias": "default"
# },
# "alarm_criteria": {
# "criteria": "if (metric[\"duration\"] >= 2) { return new AlarmStatus(OK); } return new AlarmStatus(CRITICAL);"
# }
#
# @return [String] Arguments used for the policy
attribute :args
# @!attribute [r] desiredCapacity
# @return [Fixnum] The desired capacity of the group
attribute :desired_capacity, :aliases => 'desiredCapacity'
# Basic sanity check to make sure attributes are valid
#
# @raise ArgumentError If no type is set
# @raise ArgumentError If args attribute is missing required keys (if type == 'schedule')
# @return [Boolean] Returns true if the check passes
def check_attributes
raise ArgumentError, "This #{self.name} resource requires the #{type} argument" if type.nil?
if type == 'schedule'
raise ArgumentError, "This #{self.name} resource requires the args[cron] OR args[at] argument" if args['cron'].nil? && args['at'].nil?
end
true
end
def group=(group)
attributes[:group] = group.is_a?(Group) ? group : service.groups.new(:id => group)
end
# Creates policy
# * requires attributes: :name, :type, :cooldown
#
# @return [Boolean] returns true if policy is being created
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see Policies#create
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/POST_createPolicies_v1.0__tenantId__groups__groupId__policies_Policies.html
def create
requires :name, :type, :cooldown
check_attributes
options = {}
options['name'] = name unless name.nil?
options['change'] = change unless change.nil?
options['changePercent'] = change_percent unless change_percent.nil?
options['cooldown'] = cooldown unless cooldown.nil?
options['type'] = type unless type.nil?
options['desiredCapacity'] = desired_capacity unless desired_capacity.nil?
if type == 'schedule'
options['args'] = args
end
data = service.create_policy(group.id, options)
merge_attributes(data.body['policies'][0])
true
end
# Updates the policy
#
# @return [Boolean] returns true if policy has started updating
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/PUT_putPolicy_v1.0__tenantId__groups__groupId__policies__policyId__Policies.html
def update
requires :identity
check_attributes
options = {}
options['name'] = name unless name.nil?
options['change'] = change unless change.nil?
options['changePercent'] = change_percent unless change_percent.nil?
options['cooldown'] = cooldown unless cooldown.nil?
options['type'] = type unless type.nil?
options['desiredCapacity'] = desired_capacity unless desired_capacity.nil?
if type == 'schedule'
options['args'] = args
end
data = service.update_policy(group.id, identity, options)
merge_attributes(data.body)
true
end
# Saves the policy
# Creates policy if it is new, otherwise it will update it
# @return [Boolean] true if policy has saved
def save
if persisted?
update
else
create
end
true
end
# Destroy the policy
#
# @return [Boolean] returns true if policy has started deleting
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/DELETE_deletePolicy_v1.0__tenantId__groups__groupId__policies__policyId__Policies.html
def destroy
requires :identity
service.delete_policy(group.id, identity)
true
end
# Executes the scaling policy
#
# @return [Boolean] returns true if policy has been executed
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/POST_executePolicy_v1.0__tenantId__groups__groupId__policies__policyId__execute_Policies.html
def execute
requires :identity
service.execute_policy(group.id, identity)
true
end
# Gets the associated webhooks for this policy
#
# @return [Fog::Rackspace::AutoScale::Webhooks] returns Webhooks
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
def webhooks
requires :identity
@webhooks ||= Fog::Rackspace::AutoScale::Webhooks.new({
:service => service,
:policy => self,
:group => group
})
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,116 @@
require 'fog/core/model'
module Fog
module Rackspace
class AutoScale
class Webhook < Fog::Model
# @!attribute [r] id
# @return [String] The webhook id
identity :id
# @!attribute [r] group
# @return [String] The associated group
attribute :group
# @!attribute [r] policy
# @return [String] The associated policy
attribute :policy
# @!attribute [r] name
# @return [String] The webhook name
attribute :name
# @!attribute [r] metadata
# @return [Hash] The metadata
attribute :metadata
# @!attribute [r] links
# @return [Array] The webhook links
attribute :links
# Create webhook
# * requires attribute: :name
#
# @return [Boolean] returns true if webhook is being created
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see Webhooks#create
# @see
def create
requires :name
options = {}
options['name'] = name if name
options['metadata'] = metadata if metadata
data = service.create_webhook(group.id, policy.id, options)
merge_attributes(data.body['webhooks'][0])
true
end
# Updates the webhook
#
# @return [Boolean] returns true if webhook has started updating
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/PUT_putWebhook_v1.0__tenantId__groups__groupId__policies__policyId__webhooks__webhookId__Webhooks.html
def update
requires :identity
options = {
'name' => name,
'metadata' => metadata
}
data = service.update_webhook(group.id, policy.id, identity, options)
merge_attributes(data.body)
true
end
# Saves the webhook
# Creates hook if it is new, otherwise it will update it
# @return [Boolean] true if policy has saved
def save
if persisted?
update
else
create
end
true
end
# Destroy the webhook
#
# @return [Boolean] returns true if webhook has started deleting
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/DELETE_deleteWebhook_v1.0__tenantId__groups__groupId__policies__policyId__webhooks__webhookId__Webhooks.html
def destroy
requires :identity
service.delete_webhook(group.id, policy.id, identity)
true
end
# Retrieves the URL for anonymously executing the policy webhook
# @return [String] the URL
def execution_url
requires :links
link = links.find { |l| l['rel'] == 'capability' }
link['href'] rescue nil
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,62 @@
require 'fog/core/collection'
require 'fog/rackspace/models/auto_scale/webhook'
module Fog
module Rackspace
class AutoScale
class Webhooks < Fog::Collection
model Fog::Rackspace::AutoScale::Webhook
attr_accessor :group
attr_accessor :policy
# Returns list of autoscale webhooks
#
# @return [Fog::Rackspace::AutoScale::Policies] Retrieves webhooks
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
def all
data = service.list_webhooks(group.id, policy.id).body['webhooks']
load(data)
end
# Returns an individual webhook
#
# @return [Fog::Rackspace::AutoScale::Webhook] Retrieves a webhook
# @return nil if not found
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
#
# @see http://docs.rackspace.com/cas/api/v1.0/autoscale-devguide/content/GET_getWebhook_v1.0__tenantId__groups__groupId__policies__policyId__webhooks__webhookId__Webhooks.html
def get(webhook_id)
data = service.get_webhook(group.id, policy.id, webhook_id).body['webhook']
new(data)
rescue Fog::Rackspace::AutoScale::NotFound
nil
end
# Create a webhook
#
# @return [Fog::Rackspace::AutoScale::Webhook] Returns the new webhook
#
# @raise [Fog::Rackspace::AutoScale:::NotFound] - HTTP 404
# @raise [Fog::Rackspace::AutoScale:::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::AutoScale:::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::AutoScale:::ServiceError]
def create(attributes = {})
super(attributes)
end
def new(attributes = {})
super({:group => group, :policy => policy}.merge(attributes))
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,89 @@
require 'fog/core/model'
module Fog
module Rackspace
class BlockStorage
class Snapshot < Fog::Model
AVAILABLE = 'available'
CREATING = 'creating'
DELETING = 'deleting'
ERROR = 'error'
ERROR_DELETING = 'error_deleting'
# @!attribute [r] id
# @return [String] The snapshot id
identity :id
# @!attribute [r] created_at
# @return [String] snapshot creation time
attribute :created_at, :aliases => 'createdAt'
# @!attribute [r] state
# @return [String] snapshot status
attribute :state, :aliases => 'status'
# @!attribute [rw] display_name
# @return [String] display name of snapshot
attribute :display_name
# @!attribute [rw] display_description
# @return [String] display description of snapshot
attribute :display_description
# @!attribute [rw] size
# @return [String] size of snapshot
attribute :size
# @!attribute [rw] volume_id
# @return [String] the volume_id of the snapshot
attribute :volume_id
# @!attribute [r] availability_zone
# @return [String] region of the snapshot
attribute :availability_zone
# Returns true if the snapshot is in a ready state
# @return [Boolean] returns true if snapshot is in a ready state
def ready?
state == AVAILABLE
end
# Creates the snapshot
# @param force [Boolean] Set to true to force service to create snapshot
# @raise [Fog::Rackspace::BlockStorage::IdentifierTaken] if the snapshot has been previously saved.
# @return [Boolean] returns true if snapshot is being created
# @raise [Fog::Rackspace::BlockStorage::NotFound] - HTTP 404
# @raise [Fog::Rackspace::BlockStorage::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::BlockStorage::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::BlockStorage::ServiceError]
# @note A snapshot object cannot be updated
# @note All writes to the volume should be flushed before creating the snapshot, either by un-mounting any file systems on the volume or by detaching the volume.
# @see http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/POST_createSnapshot__v1__tenant_id__snapshots.html
def save(force = false)
requires :volume_id
raise IdentifierTaken.new('Resaving may cause a duplicate snapshot to be created') if persisted?
data = service.create_snapshot(volume_id, {
:display_name => display_name,
:display_description => display_description,
:force => force
})
merge_attributes(data.body['snapshot'])
true
end
# Destroys snapshot
# @return [Boolean] returns true if snapshot was deleted
# @raise [Fog::Rackspace::BlockStorage::NotFound] - HTTP 404
# @raise [Fog::Rackspace::BlockStorage::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::BlockStorage::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::BlockStorage::ServiceError]
# @see http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/DELETE_deleteSnapshot__v1__tenant_id__snapshots.html
def destroy
requires :identity
service.delete_snapshot(identity)
true
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,39 @@
require 'fog/core/collection'
require 'fog/rackspace/models/block_storage/snapshot'
module Fog
module Rackspace
class BlockStorage
class Snapshots < Fog::Collection
model Fog::Rackspace::BlockStorage::Snapshot
# Returns list of snapshots
# @return [Fog::Rackspace::BlockStorage::Snapshots] Retrieves a snapshots
# @raise [Fog::Rackspace::BlockStorage::NotFound] - HTTP 404
# @raise [Fog::Rackspace::BlockStorage::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::BlockStorage::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::BlockStorage::ServiceError]
# @see http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/GET_getSnapshotsSimple__v1__tenant_id__snapshots.html
def all
data = service.list_snapshots.body['snapshots']
load(data)
end
# Retrieves snapshot
# @param [String] snapshot_id for snapshot to be returned
# @return [Fog::Rackspace::BlockStorage::Volume]
# @raise [Fog::Rackspace::BlockStorage::NotFound] - HTTP 404
# @raise [Fog::Rackspace::BlockStorage::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::BlockStorage::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::BlockStorage::ServiceError]
# @see http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/GET_getSnapshot__v1__tenant_id__snapshots.html
def get(snapshot_id)
data = service.get_snapshot(snapshot_id).body['snapshot']
new(data)
rescue Fog::Rackspace::BlockStorage::NotFound
nil
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,134 @@
require 'fog/core/model'
module Fog
module Rackspace
class BlockStorage
class Volume < Fog::Model
AVAILABLE = 'available'
ATTACHING = 'attaching'
CREATING = 'creating'
DELETING = 'deleting'
ERROR = 'error'
ERROR_DELETING = 'error_deleting'
IN_USE = 'in-use'
# @!attribute [r] id
# @return [String] The volume id
identity :id
# @!attribute [r] created_at
# @return [String] volume creation date
attribute :created_at, :aliases => 'createdAt'
# @!attribute [r] state
# @return [String] volume status
attribute :state, :aliases => 'status'
# @!attribute [rw] display_name
# @return [String] display name of volume
attribute :display_name
# @!attribute [rw] display_description
# @return [String] display description of volume
attribute :display_description
# @!attribute [rw] size
# @return [String] size of the volume in GB (100 GB minimum)
attribute :size
# @!attribute [r] attachments
# @return [Array<Hash>] returns an array of hashes containing attachment information
attribute :attachments
# @!attribute [rw] volume_type
# @return [String] type of volume
attribute :volume_type
# @!attribute [r] availability_zone
# @return [String] region of the volume
attribute :availability_zone
# @!attribute [rw] image_id
# @return [String] The ID of an image used to create a bootable volume.
attribute :image_id, :aliases => ['image', 'imageRef'], :squash => 'id'
# Returns true if the volume is in a ready state
# @return [Boolean] returns true if volume is in a ready state
def ready?
state == AVAILABLE
end
# Returns true if the volume is attached
# @return [Boolean] true if the volume is attached
def attached?
state == IN_USE
end
# Returns a list of snapshots associated with the volume
# @return [Fog::Rackspace::BlockStorage::Snapshots]
# @raise [Fog::Rackspace::BlockStorage::NotFound] - HTTP 404
# @raise [Fog::Rackspace::BlockStorage::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::BlockStorage::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::BlockStorage::ServiceError]
def snapshots
service.snapshots.select { |s| s.volume_id == identity }
end
# Creates a snapshot from the current volume
# @param [Hash] options
# @option options [String] :display_name of snapshot
# @option options [String] :display_description of snapshot
# @option options [Boolean] :force - If set to true, snapshot will be taken even if volume is still mounted.
# @return [Fog::Rackspace::BlockStorage::Snapshot]
# @raise [Fog::Rackspace::BlockStorage::NotFound] - HTTP 404
# @raise [Fog::Rackspace::BlockStorage::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::BlockStorage::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::BlockStorage::ServiceError]
# @note All writes to the volume should be flushed before creating the snapshot, either by un-mounting any file systems on the volume or by detaching the volume.
# @see http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/POST_createSnapshot__v1__tenant_id__snapshots.html
def create_snapshot(options={})
requires :identity
service.snapshots.create(options.merge(:volume_id => identity))
end
# Creates volume
# @raise [Fog::Rackspace::BlockStorage::IdentifierTaken] if the volume has been previously saved.
# @return [Boolean] returns true if volume was successfully created
# @raise [Fog::Rackspace::BlockStorage::NotFound] - HTTP 404
# @raise [Fog::Rackspace::BlockStorage::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::BlockStorage::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::BlockStorage::ServiceError]
# @note A volume object cannot be updated
# @see http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/POST_createVolume__v1__tenant_id__volumes.html
def save
requires :size
raise IdentifierTaken.new('Resaving may cause a duplicate volume to be created') if persisted?
data = service.create_volume(size, {
:display_name => display_name,
:display_description => display_description,
:volume_type => volume_type,
:availability_zone => availability_zone,
:snapshot_id => attributes[:snapshot_id],
:image_id => attributes[:image_id]
})
merge_attributes(data.body['volume'])
true
end
# Destroys Volume
# @return [Boolean] returns true if volume was deleted
# @raise [Fog::Rackspace::BlockStorage::NotFound] - HTTP 404
# @raise [Fog::Rackspace::BlockStorage::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::BlockStorage::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::BlockStorage::ServiceError]
# @note You cannot delete a volume until all of its dependent snaphosts have been deleted.
# @see http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/DELETE_deleteVolume__v1__tenant_id__volumes.html
def destroy
requires :identity
service.delete_volume(identity)
true
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,19 @@
require 'fog/core/model'
module Fog
module Rackspace
class BlockStorage
class VolumeType < Fog::Model
# @!attribute [r] id
# @return [String] The volume type id
identity :id
# @!attribute [r] name
# @return [String] The name of the volume type
attribute :name
attribute :extra_specs
end
end
end
end

Просмотреть файл

@ -0,0 +1,39 @@
require 'fog/core/collection'
require 'fog/rackspace/models/block_storage/volume_type'
module Fog
module Rackspace
class BlockStorage
class VolumeTypes < Fog::Collection
model Fog::Rackspace::BlockStorage::VolumeType
# Returns list of volume types
# @return [Fog::Rackspace::BlockStorage::VolumeTypes] Retrieves a list volume types.
# @raise [Fog::Rackspace::BlockStorage::NotFound] - HTTP 404
# @raise [Fog::Rackspace::BlockStorage::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::BlockStorage::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::BlockStorage::ServiceError]
# @see http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/GET_getVolumeTypes__v1__tenant_id__types.html
def all
data = service.list_volume_types.body['volume_types']
load(data)
end
# Retrieves volume type
# @param [String] volume_type_id for volume_type to be returned
# @return [Fog::Rackspace::BlockStorage::VolumeType]
# @raise [Fog::Rackspace::BlockStorage::NotFound] - HTTP 404
# @raise [Fog::Rackspace::BlockStorage::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::BlockStorage::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::BlockStorage::ServiceError]
# @see http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/GET_getVolumeType__v1__tenant_id__types.html
def get(volume_type_id)
data = service.get_volume_type(volume_type_id).body['volume_type']
new(data)
rescue Fog::Rackspace::BlockStorage::NotFound
nil
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,39 @@
require 'fog/core/collection'
require 'fog/rackspace/models/block_storage/volume'
module Fog
module Rackspace
class BlockStorage
class Volumes < Fog::Collection
model Fog::Rackspace::BlockStorage::Volume
# Returns list of volumes
# @return [Fog::Rackspace::BlockStorage::Volumes] Retrieves a volumes
# @raise [Fog::Rackspace::BlockStorage::NotFound] - HTTP 404
# @raise [Fog::Rackspace::BlockStorage::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::BlockStorage::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::BlockStorage::ServiceError]
# @see http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/GET_getVolumesSimple__v1__tenant_id__volumes.html
def all
data = service.list_volumes.body['volumes']
load(data)
end
# Retrieves volume
# @param [String] volume_id for snapshot to be returned
# @return [Fog::Rackspace::BlockStorage::Volume]
# @raise [Fog::Rackspace::BlockStorage::NotFound] - HTTP 404
# @raise [Fog::Rackspace::BlockStorage::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::BlockStorage::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::BlockStorage::ServiceError]
# @see http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/GET_getVolume__v1__tenant_id__volumes.html
def get(volume_id)
data = service.get_volume(volume_id).body['volume']
new(data)
rescue Fog::Rackspace::BlockStorage::NotFound
nil
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,42 @@
require 'fog/core/model'
module Fog
module Compute
class Rackspace
class Flavor < Fog::Model
identity :id
attribute :disk
attribute :name
attribute :ram
def bits
64
end
def cores
# Each server is assigned 4 virtual cores and
# given a percentage of CPU cycles based on size
4 * case ram
when 256
1/64.0
when 512
1/32.0
when 1024
1/16.0
when 2048
1/8.0
when 4096
1/4.0
when 8192
1/2.0
when 15872
1
when 30720
2
end
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,24 @@
require 'fog/core/collection'
require 'fog/rackspace/models/compute/flavor'
module Fog
module Compute
class Rackspace
class Flavors < Fog::Collection
model Fog::Compute::Rackspace::Flavor
def all
data = service.list_flavors_detail.body['flavors']
load(data)
end
def get(flavor_id)
data = service.get_flavor_details(flavor_id).body['flavor']
new(data)
rescue Fog::Compute::Rackspace::NotFound
nil
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,44 @@
require 'fog/core/model'
module Fog
module Compute
class Rackspace
class Image < Fog::Model
identity :id
attribute :name
attribute :created_at, :aliases => 'created'
attribute :updated_at, :aliases => 'updated'
attribute :progress
attribute :status
attribute :server_id, :aliases => 'serverId'
def server=(new_server)
requires :id
self.server_id = new_server.id
end
def destroy
requires :id
service.delete_image(id)
true
end
def ready?
status == 'ACTIVE'
end
def save
raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if persisted?
requires :server_id
data = service.create_image(server_id, 'name' => name)
merge_attributes(data.body['image'])
true
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,31 @@
require 'fog/core/collection'
require 'fog/rackspace/models/compute/image'
module Fog
module Compute
class Rackspace
class Images < Fog::Collection
model Fog::Compute::Rackspace::Image
attribute :server
def all
data = service.list_images_detail.body['images']
models = load(data)
if server
self.replace(self.select {|image| image.server_id == server.id})
else
models
end
end
def get(image_id)
data = service.get_image_details(image_id).body['image']
new(data)
rescue Fog::Compute::Rackspace::NotFound
nil
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,102 @@
require 'fog/compute/models/server'
module Fog
module Compute
class Rackspace
class Server < Fog::Compute::Server
identity :id
attribute :addresses
attribute :flavor_id, :aliases => 'flavorId', :type => :integer
attribute :host_id, :aliases => 'hostId'
attribute :image_id, :aliases => 'imageId', :type => :integer
attribute :metadata
attribute :name
attribute :personality
attribute :progress
attribute :state, :aliases => 'status'
attr_reader :password
def initialize(attributes={})
self.flavor_id ||= 1 # 256 server
self.image_id ||= 49 # Ubuntu 10.04 LTS 64bit
super
end
def destroy
requires :id
service.delete_server(id)
true
end
def flavor
requires :flavor_id
service.flavors.get(flavor_id)
end
def image
requires :image_id
service.images.get(image_id)
end
def images
requires :id
service.images(:server => self)
end
def private_ip_address
addresses['private'].first
end
def public_ip_address
addresses['public'].first
end
def ready?
self.state == 'ACTIVE'
end
def reboot(type = 'SOFT')
requires :id
service.reboot_server(id, type)
true
end
def save(options = {})
raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if persisted?
requires :flavor_id, :image_id
options = {
'metadata' => metadata,
'name' => name,
'personality' => personality
}
options = options.reject {|key, value| value.nil?}
data = service.create_server(flavor_id, image_id, options)
merge_attributes(data.body['server'])
true
end
def setup(credentials = {})
requires :ssh_ip_address, :identity, :public_key, :username
Fog::SSH.new(ssh_ip_address, username, credentials).run([
%{mkdir .ssh},
%{echo "#{public_key}" >> ~/.ssh/authorized_keys},
%{passwd -l #{username}},
%{echo "#{Fog::JSON.encode(attributes)}" >> ~/attributes.json},
%{echo "#{Fog::JSON.encode(metadata)}" >> ~/metadata.json}
])
rescue Errno::ECONNREFUSED
sleep(1)
retry
end
private
def adminPass=(new_admin_pass)
@password = new_admin_pass
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,32 @@
require 'fog/core/collection'
require 'fog/rackspace/models/compute/server'
module Fog
module Compute
class Rackspace
class Servers < Fog::Collection
model Fog::Compute::Rackspace::Server
def all
data = service.list_servers_detail.body['servers']
load(data)
end
def bootstrap(new_attributes = {})
server = create(new_attributes)
server.wait_for { ready? }
server.setup(:password => server.password)
server
end
def get(server_id)
if server = service.get_server_details(server_id).body['server']
new(server)
end
rescue Fog::Compute::Rackspace::NotFound
nil
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,61 @@
require 'fog/core/model'
module Fog
module Compute
class RackspaceV2
class Attachment < Fog::Model
# @!attribute [r] server_id
# @return [String] The server id
attribute :server_id, :aliases => 'serverId'
# @!attribute [r] volume_id
# @return [String] The volume id
attribute :volume_id, :aliases => 'volumeId'
# @!attribute [r] device
# @return [String]device name of the device /dev/xvd[a-p]
attribute :device
def initialize(new_attributes = {})
super(new_attributes)
server_id = server.id if server #server id should come from collection
self
end
# Attaches volume to volume to server.
# Requires :server_id, :volume_id, and device to be populated
# @return [Boolean] true if volume is attaching
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Attach_Volume_to_Server.html
def save
requires :server_id, :volume_id, :device
data = service.attach_volume(server_id, volume_id, device)
merge_attributes(data.body['volumeAttachment'])
true
end
# Detaches volume from server
# @return [Boolean] true if volume is detaching
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Delete_Volume_Attachment.html
def destroy
requires :server_id, :volume_id
service.delete_attachment(server_id, volume_id)
true
end
alias_method :detach, :destroy
private
def server
collection.server
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,38 @@
require 'fog/core/collection'
require 'fog/rackspace/models/compute_v2/attachment'
module Fog
module Compute
class RackspaceV2
class Attachments < Fog::Collection
model Fog::Compute::RackspaceV2::Attachment
attr_accessor :server
# Retrieves attachments belonging to server
# @return [Fog::Compute::RackspaceV2::Attachments] list of attachments
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see Server#attachments
def all
data = service.list_attachments(server.id).body['volumeAttachments']
load(data)
end
# Retrieves attachment belonging to server
# @param [String] volume_id
# @return [Fog::Compute::RackspaceV2::Attachment] attachment for volume id
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
def get(volume_id)
data = service.get_attachment(server.id, volume_id).body['volumeAttachment']
data && new(data)
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,33 @@
require 'fog/core/model'
module Fog
module Compute
class RackspaceV2
class Flavor < Fog::Model
# @!attribute [r] id
# @return [String] The flavor id
identity :id
# @!attribute [r] name
# @return [String] flavor name
attribute :name
# @!attribute [r] rame
# @return [Fixnum] ram in MB
attribute :ram
# @!attribute [r] disk
# @return [String] disk space in GB
attribute :disk
# @!attribute [r] vcpus
# @return [Fixnum] number of virtual CPUs
attribute :vcpus
# @!attribute [r] links
# @return [Array] flavor links.
attribute :links
end
end
end
end

Просмотреть файл

@ -0,0 +1,39 @@
require 'fog/core/collection'
require 'fog/rackspace/models/compute_v2/flavor'
module Fog
module Compute
class RackspaceV2
class Flavors < Fog::Collection
model Fog::Compute::RackspaceV2::Flavor
# Retrieves information for all available flavors
# @return [Fog::Compute::RackspaceV2::Flavors] list of flavors
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @note Fog's currentl implementation only returns 1000 flavors.
def all
data = service.list_flavors_detail.body['flavors']
load(data)
end
# Retrieve image
# @param [String] flavor_id id of flavor
# @return [Fog::Compute::RackspaceV2::Flavor] flavor
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Get_Flavor_Details-d1e4317.html
def get(flavor_id)
data = service.get_flavor(flavor_id).body['flavor']
new(data)
rescue Fog::Compute::RackspaceV2::NotFound
nil
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,117 @@
require 'fog/core/model'
module Fog
module Compute
class RackspaceV2
class Image < Fog::Model
UNKNOWN = 'UNKNOWN'
ACTIVE = 'ACTIVE'
SAVING = 'SAVING'
ERROR = 'ERROR'
DELETED = 'DELETED'
# @!attribute [r] id
# @return [String] The server id
identity :id
# @!attribute [r] name
# @return [String] The image name.
attribute :name
# @!attribute [r] created
# @return [String] The time stamp for the creation date.
attribute :created
# @!attribute [r] updated
# @return [String] The time stamp for the last update.
attribute :updated
# @!attribute [r] state
# @return [String] image status.
attribute :state, :aliases => 'status'
# @!attribute [r] user_id
# @return [String] The user Id.
attribute :user_id
# @!attribute [r] tenant_id
# @return [String] The tenant Id.
attribute :tenant_id
# @!attribute [r] progress
# @return [Fixnum] The build completion progress, as a percentage. Value is from 0 to 100.
attribute :progress
attribute :minDisk
attribute :minRam
# @!attribute [rw] disk_config
# @return [String<AUTO, MANUAL>] The disk configuration value.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ch_extensions.html#diskconfig_attribute
#
# The disk configuration value.
# * AUTO - The server is built with a single partition the size of the target flavor disk. The file system is automatically adjusted to fit the entire partition.
# This keeps things simple and automated. AUTO is valid only for images and servers with a single partition that use the EXT3 file system.
# This is the default setting for applicable Rackspace base images.
#
# * MANUAL - The server is built using whatever partition scheme and file system is in the source image. If the target flavor disk is larger,
# the remaining disk space is left unpartitioned. This enables images to have non-EXT3 file systems, multiple partitions,
# and so on, and enables you to manage the disk configuration.
attribute :disk_config, :aliases => 'OS-DCF:diskConfig'
# @!attribute [r] links
# @return [Array] image links.
attribute :links
def initialize(attributes={})
@service = attributes[:service]
super
end
# Image metadata
# @return [Fog::Compute::RackspaceV2::Metadata] Collection of Fog::Compute::RackspaceV2::Metadatum objects containing metadata key value pairs.
def metadata
@metadata ||= begin
Fog::Compute::RackspaceV2::Metadata.new({
:service => service,
:parent => self
})
end
end
# Set server metadata
# @param [Hash] hash contains key value pairs
def metadata=(hash={})
metadata.from_hash(hash)
end
# Is image is in ready state
# @param [String] ready_state By default state is ACTIVE
# @param [Array,String] error_states By default state is ERROR
# @return [Boolean] returns true if server is in a ready state
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @raise [Fog::Compute::RackspaceV2::InvalidImageStateException] if server state is an error state
def ready?(ready_state = ACTIVE, error_states=[ERROR])
if error_states
error_states = Array(error_states)
raise InvalidImageStateException.new(ready_state, state) if error_states.include?(state)
end
state == ready_state
end
# Destroy image
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
def destroy
requires :identity
service.delete_image(identity)
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,73 @@
require 'fog/core/collection'
require 'fog/rackspace/models/compute_v2/image'
module Fog
module Compute
class RackspaceV2
class Images < Fog::Collection
# @!attribute [rw] name
# @return [String] Given a string value x, filters the list of images by image name.
attribute :name
# @!attribute [rw] status
# @return [String] Given a string value x, filters the list of images by status.
# @note Possible values are ACTIVE, DELETED, ERROR, SAVING, and UNKNOWN.
attribute :status
# @!attribute [rw] marker
# @return [String] Given a string value x, return object names greater in value than the specified marker.
# @see http://docs.rackspace.com/files/api/v1/cf-devguide/content/List_Large_Number_of_Objects-d1e1521.html
attribute :marker
# @!attribute [rw] limit
# @return [Integer] For an integer value n, limits the number of results to at most n values.
# @see http://docs.rackspace.com/files/api/v1/cf-devguide/content/List_Large_Number_of_Objects-d1e1521.html
attribute :limit
# @!attribute [rw] type
# @return [String] Given a string value x, filters the list of images by type.
# @note Valid values are BASE and SNAPSHOT
attribute :type
model Fog::Compute::RackspaceV2::Image
# Returns list of images
# @return [Fog::Compute::RackspaceV2::Images] Retrieves a list images.
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @note Fog's current implementation only returns 1000 images.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/List_Images-d1e4435.html
def all(options = {})
options = {
'name' => name,
'status' => status,
'marker' => marker,
'limit' => limit,
'type' => type
}.merge!(options)
merge_attributes(options)
data = service.list_images_detail(options).body['images']
load(data)
end
# Retrieve image
# @param [String] image_id id of image
# @return [Fog::Compute::RackspaceV2:Image] image
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Get_Image_Details-d1e4848.html
def get(image_id)
data = service.get_image(image_id).body['image']
new(data)
rescue Fog::Compute::RackspaceV2::NotFound
nil
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,54 @@
require 'fog/core/model'
module Fog
module Compute
class RackspaceV2
class KeyPair < Fog::Model
# @!attribute [rw] name
# @return [String] the keypair name
identity :name
# @!attribute [r] public_key
# @return [String] the public key
attribute :public_key
# @!attribute [r] private_key
# @return [String] the private key
attribute :private_key
# @!attribute [r] user_id
# @return [String] the user_id associated to
attribute :user_id
# @!attribute [r] fingerprint
# @return [String] unique fingerprint
attribute :fingerprint
# Creates a keypair
# @return [Boolean] true if the keypair is successfully created
# @raise [Fog::Compute::RackspaceV2::NotFound]
# @raise [Fog::Compute::RackspaceV2::BadRequest]
# @raise [Fog::Compute::RackspaceV2::InternalServerError]
# @raise [Fog::Compute::RackspaceV2::ServiceError]
def save
requires :name
data = service.create_keypair(name, attributes)
merge_attributes(data.body['keypair'])
data.body['keypair']['name'] == name
end
# Destroys a keypair
# @return [Boolean] true if the keypair is successfully deleted
# @raise [Fog::Compute::RackspaceV2::NotFound]
# @raise [Fog::Compute::RackspaceV2::BadRequest]
# @raise [Fog::Compute::RackspaceV2::InternalServerError]
# @raise [Fog::Compute::RackspaceV2::ServiceError]
def destroy
requires :identity
service.delete_keypair(identity)
true
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,40 @@
require 'fog/core/collection'
require 'fog/rackspace/models/compute_v2/key_pair'
module Fog
module Compute
class RackspaceV2
class KeyPairs < Fog::Collection
model Fog::Compute::RackspaceV2::KeyPair
# Fetch the list of known keypairs
# @return [Fog::Compute::RackspaceV2::Keypairs] the retreived keypairs
# @raise [Fog::Compute::RackspaceV2::NotFound]
# @raise [Fog::Compute::RackspaceV2::BadRequest]
# @raise [Fog::Compute::RackspaceV2::InternalServerError]
# @raise [Fog::Compute::RackspaceV2::ServiceError]
def all
data = []
service.list_keypairs.body['keypairs'].each do |kp|
data << kp['keypair'] if kp['keypair']
end
load(data)
end
# Fetch keypair details
# @param [String] key_name name of the key to request
# @return [Fog::Compute::RackspaceV2::Keypair] the requested keypair or 'nil' when not found
# @raise [Fog::Compute::RackspaceV2::BadRequest]
# @raise [Fog::Compute::RackspaceV2::InternalServerError]
# @raise [Fog::Compute::RackspaceV2::ServiceError]
def get(key_name)
begin
new(service.get_keypair(key_name).body['keypair'])
rescue Fog::Compute::RackspaceV2::NotFound
nil
end
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,40 @@
module Fog
module Compute
class RackspaceV2
module MetaParent
# Parent of metadata
# @return [#parent] parent of metadata
def parent
@parent
end
# Sets parent of metadata
# @param [#parent] new_parent of metadata
def parent=(new_parent)
@parent = new_parent
end
# Collection type for parent
# @return [String] collection type
# @raise [RuntimeError] raises excpetion if collection type for parent is unknown
def collection_name
if parent.class == Fog::Compute::RackspaceV2::Image
return "images"
elsif parent.class == Fog::Compute::RackspaceV2::Server
return "servers"
else
raise "Metadata is not supported for this model type."
end
end
# Converts metadata to hash
# @return [Hash] hash containing key value pairs for metadata
def metas_to_hash(metas)
hash = {}
metas.each { |meta| hash[meta.key] = meta.value }
hash
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,108 @@
require 'fog/core/collection'
require 'fog/rackspace/models/compute_v2/meta_parent'
require 'fog/rackspace/models/compute_v2/metadatum'
require 'fog/rackspace/models/compute_v2/image'
require 'fog/rackspace/models/compute_v2/server'
module Fog
module Compute
class RackspaceV2
class Metadata < Fog::Collection
model Fog::Compute::RackspaceV2::Metadatum
include Fog::Compute::RackspaceV2::MetaParent
# Retrieves all of the metadata from server
# @return [Fog::Compute::RackspaceV2::Metadatum] list of metadatum
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
def all
requires :parent
return unless parent.identity
data = service.list_metadata(collection_name, parent.id).body['metadata']
from_hash(data)
end
# Retrieves specific metadata from server
# @param [String] key for metadatum
# @return [Fog::Compute::RackspaceV2::Metadatum] metadatum
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
def get(key)
requires :parent
data = service.get_metadata_item(collection_name, parent.id, key).body["meta"]
datum = data.first
new(:key => datum[0], :value => datum[1])
rescue Fog::Compute::RackspaceV2::NotFound
nil
end
# Retrieve specific value for key from Metadata.
# * If key is of type String, this method will return the value of the metadatum
# * If key is of type Fixnum, this method will return a Fog::Compute::RackspaceV2::Metadatum object (legacy)
# @param [#key] key
# @return [#value]
def [](key)
return super(key) if key.is_a?(Integer)
return nil unless key
datum = self.find {|datum| datum.key == key || datum.key == key.to_sym }
datum ? datum.value : nil
end
# Set value for key.
# * If key is of type String, this method will set/add the value to Metadata
# * If key is of type Fixnum, this method will set a Fog::Compute::RackspaceV2::Metadatum object (legacy)
# @param [#key] key
# @return [String]
def []=(key, value)
return super(key,value) if key.is_a?(Integer)
return nil unless key
datum = self.find {|datum| datum.key == key || datum.key == key.to_sym }
if datum
datum.value = value
else
self << Fog::Compute::RackspaceV2::Metadatum.new(:key => key, :value => value, :service => service, :parent => parent)
end
value
end
# Saves the current metadata on server
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
def save
requires :parent
service.set_metadata(collection_name, parent.id, to_hash)
end
# Creates new metadata
def new(attributes = {})
super({ :parent => parent }.merge!(attributes))
end
# Resets metadata using data from hash
# @param hash hash containing key value pairs used to populate metadata.
# @note This will remove existing data
def from_hash(hash)
return unless hash
metas = []
hash.each_pair {|k,v| metas << {:key => k, :value => v} }
load(metas)
end
# Converts metadata object to hash
# @return [Hash] hash of metadata key value pairs
def to_hash
h = {}
self.each { |datum| h[datum.key] = datum.value }
h
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,39 @@
require 'fog/core/model'
require 'fog/rackspace/models/compute_v2/meta_parent'
module Fog
module Compute
class RackspaceV2
class Metadatum < Fog::Model
include Fog::Compute::RackspaceV2::MetaParent
identity :key
attribute :value
# Remove metadatum from server
# @return [Boolean] return true if metadatum is deleting
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
def destroy
requires :identity
service.delete_metadata_item(collection_name, parent.id, key)
true
end
# Save metadatum on server
# @return [Boolean] return true if metadatum is saving
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
def save
requires :identity, :value
service.set_metadata_item(collection_name, parent.id, key, value)
true
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,27 @@
module Fog
module Compute
class RackspaceV2
class Network < Fog::Model
identity :id
attribute :label
attribute :cidr
def save
requires :label, :cidr
data = service.create_network(label, cidr)
merge_attributes(data.body['network'])
true
end
def destroy
requires :identity
service.delete_network(identity)
true
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,23 @@
require 'fog/rackspace/models/compute_v2/network'
module Fog
module Compute
class RackspaceV2
class Networks < Fog::Collection
model Fog::Compute::RackspaceV2::Network
def all
data = service.list_networks.body['networks']
load(data)
end
def get(id)
data = service.get_network(id).body['network']
new(data)
rescue Fog::Compute::RackspaceV2::NotFound
nil
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,631 @@
# -*- coding: utf-8 -*-
require 'fog/compute/models/server'
require 'fog/rackspace/models/compute_v2/metadata'
module Fog
module Compute
class RackspaceV2
class Server < Fog::Compute::Server
# States
ACTIVE = 'ACTIVE'
BUILD = 'BUILD'
DELETED = 'DELETED'
ERROR = 'ERROR'
HARD_REBOOT = 'HARD_REBOOT'
MIGRATING = 'MIGRATING'
PASSWORD = 'PASSWORD'
REBOOT = 'REBOOT'
REBUILD = 'REBUILD'
RESCUE = 'RESCUE'
RESIZE = 'RESIZE'
REVERT_RESIZE = 'REVERT_RESIZE'
SUSPENDED = 'SUSPENDED'
UNKNOWN = 'UNKNOWN'
VERIFY_RESIZE = 'VERIFY_RESIZE'
# @!attribute [r] id
# @return [String] The server id
identity :id
# @!attribute [rw] name
# @return [String] The server name.
attribute :name
# @!attribute [r] created
# @return [String] The time stamp for the creation date.
attribute :created
# @!attribute [r] updated
# @return [String] The time stamp for the last update.
attribute :updated
# @!attribute [r] host Id
# The host Id.
# The compute provisioning algorithm has an anti-affinity property that attempts to spread customer VMs across hosts.
# Under certain situations, VMs from the same customer might be placed on the same host.
# hostId represents the host your server runs on and can be used to determine this scenario if it is relevant to your application.
# HostId is unique per account and is not globally unique.
# @return [String] host id.
attribute :host_id, :aliases => 'hostId'
# @!attribute [r] state
# @return [String] server status.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/List_Servers-d1e2078.html#server_status
attribute :state, :aliases => 'status'
# @!attribute [r] state_ext
# @return [String] server (extended) status.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/List_Servers-d1e2078.html#server_status
attribute :state_ext, :aliases => 'OS-EXT-STS:task_state'
# @!attribute [r] progress
# @return [Fixnum] The build completion progress, as a percentage. Value is from 0 to 100.
attribute :progress
# @!attribute [r] user_id
# @return [String] The user Id.
attribute :user_id
# @!attribute [r] tenant_id
# @return [String] The tenant Id.
attribute :tenant_id
# @!attribute [r] links
# @return [Array] Server links.
attribute :links
# @!attribute [rw] personality
# @note This attribute is only used for server creation. This field will be nil on subsequent retrievals.
# @return [Hash] Hash containing data to inject into the file system of the cloud server instance during server creation.
# @example To inject fog.txt into file system
# :personality => [{ :path => '/root/fog.txt',
# :contents => Base64.encode64('Fog was here!')
# }]
# @see #create
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Server_Personality-d1e2543.html
attribute :personality
# @!attribute [rw] ipv4_address
# @return [String] The public IP version 4 access address.
# @note This field will populate once the server is ready to use.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Server_Primary_Addresses-d1e2558.html
attribute :ipv4_address, :aliases => 'accessIPv4'
# @!attribute [rw] ipv6_address
# @return [String] The public IP version 6 access address.
# @note This field will populate once the server is ready to use.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Server_Primary_Addresses-d1e2558.html
attribute :ipv6_address, :aliases => 'accessIPv6'
# @!attribute [rw] disk_config
# @return [String<AUTO, MANUAL>] The disk configuration value.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ch_extensions.html#diskconfig_attribute
#
# The disk configuration value.
# * AUTO - The server is built with a single partition the size of the target flavor disk. The file system is automatically adjusted to fit the entire partition.
# This keeps things simple and automated. AUTO is valid only for images and servers with a single partition that use the EXT3 file system.
# This is the default setting for applicable Rackspace base images.
#
# * MANUAL - The server is built using whatever partition scheme and file system is in the source image. If the target flavor disk is larger,
# the remaining disk space is left unpartitioned. This enables images to have non-EXT3 file systems, multiple partitions,
# and so on, and enables you to manage the disk configuration.
attribute :disk_config, :aliases => 'OS-DCF:diskConfig'
# @!attribute [rw] config_drive_ext
# @return [Boolean] whether a read-only configuration drive is attached
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/config_drive_ext.html
attribute :config_drive
# @!attribute [rw] user_data
# @return [Boolean] User-data
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/config_drive_ext.html
attribute :user_data
# @!attribute [r] bandwidth
# @return [Array] The amount of bandwidth used for the specified audit period.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ch_extensions.html#bandwidth_extension
attribute :bandwidth, :aliases => 'rax-bandwidth:bandwidth'
# @!attribute [r] address
# @return [Hash<String, Array[Hash]>] IP addresses allocated for server by network
# @example
# {
# "public" => [
# {"version"=>4, "addr"=>"166.78.105.63"},
# {"version"=>6, "addr"=>"2001:4801:7817:0072:0fe1:75e8:ff10:61a9"}
# ],
# "private"=> [{"version"=>4, "addr"=>"10.177.18.209"}]
# }
attribute :addresses
# @!attribute [r] flavor_id
# @return [String] The flavor Id.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/List_Flavors-d1e4188.html
attribute :flavor_id, :aliases => 'flavor', :squash => 'id'
# @!attribute [r] image_id
# @return [String] The image Id.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/List_Images-d1e4435.html
attribute :image_id, :aliases => 'image', :squash => 'id'
# @!attribute [w] boot_volume_id
# @return [String] The ID of a bootable volume from the BlockStorage service.
# @see http://developer.openstack.org/api-ref-compute-v2-ext.html#ext-os-block-device-mapping-v2-boot
attribute :boot_volume_id
# @!attribute [w] boot_image_id
# @return [String] The ID of an image to create a bootable volume from.
# @see http://developer.openstack.org/api-ref-compute-v2-ext.html#ext-os-block-device-mapping-v2-boot
attribute :boot_image_id
# @!attribute [rw] password
# @return [String] Password for system adminstrator account.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Server_Passwords-d1e2510.html
# @note Can be set while creating a server, but use change_admin_password instead of save/update for changes.
attribute :password
# @!attribute [rw] key_name
# @return [String] The name of the key_pair used for server.
# @note The key_pair/key_name is used to specify the keypair used for server creation. It is not populated by cloud servers.
attribute :key_name
def initialize(attributes={})
@service = attributes[:service]
super
end
alias_method :access_ipv4_address, :ipv4_address
alias_method :access_ipv4_address=, :ipv4_address=
alias_method :access_ipv6_address, :ipv6_address
alias_method :access_ipv6_address=, :ipv6_address=
# Server metadata
# @return [Fog::Compute::RackspaceV2::Metadata] metadata key value pairs.
def metadata
@metadata ||= begin
Fog::Compute::RackspaceV2::Metadata.new({
:service => service,
:parent => self
})
end
end
# Set server metadata
# @param [Hash] hash contains key value pairs
def metadata=(hash={})
metadata.from_hash(hash)
end
# Returns the key pair based on the key_name of the server
# @return [KeyPair]
# @note The key_pair/key_name is used to specify the keypair used for server creation. It is not populated by cloud servers.
def key_pair
requires :key_name
service.key_pairs.get(key_name)
end
# Sets the key_pair used by the server.
# @param new_keypair [KeyPair] key_pair object for server
# @note The key_pair/key_name is used to specify the keypair used for server creation. It is not populated by cloud servers.
def key_pair=(new_keypair)
if new_keypair.is_a?(String)
Fog::Logger.deprecation("#key_pair= should be used to set KeyPair objects. Please use #key_name method instead")
self.key_name = new_keypair
else
self.key_name = new_keypair && new_keypair.name
end
end
# Saves the server.
# Creates server if it is new, otherwise it will update server attributes name, accessIPv4, and accessIPv6.
# @return [Boolean] true if server has started saving
def save(options = {})
if persisted?
update
else
create(options)
end
true
end
# Creates server
# * requires attributes: service:, :name, :image_id, and :flavor_id
# * optional attributes :disk_config, :metadata, :personality, :config_drive, :boot_volume_id, :boot_image_id
# * :image_id should be "" if :boot_volume_id or :boot_image_id are provided.
# @return [Boolean] returns true if server is being created
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @note You should use servers.create to create servers instead calling this method directly
# @see Servers#create
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/CreateServers.html
#
# * State Transitions
# * BUILD -> ACTIVE
# * BUILD -> ERROR (on error)
def create(options)
requires :name, :image_id, :flavor_id
modified_options = Marshal.load(Marshal.dump(options))
if attributes[:keypair]
Fog::Logger.deprecation(":keypair has been depreciated. Please use :key_name instead.")
modified_options[:key_name] = attributes[:keypair]
end
modified_options[:password] ||= attributes[:password] unless password.nil?
modified_options[:networks] ||= attributes[:networks]
modified_options[:disk_config] = disk_config unless disk_config.nil?
modified_options[:metadata] = metadata.to_hash unless @metadata.nil?
modified_options[:personality] = personality unless personality.nil?
modified_options[:config_drive] = config_drive unless config_drive.nil?
modified_options[:user_data] = user_data_encoded unless user_data_encoded.nil?
modified_options[:key_name] ||= attributes[:key_name]
modified_options[:boot_volume_id] ||= attributes[:boot_volume_id]
modified_options[:boot_image_id] ||= attributes[:boot_image_id]
if modified_options[:networks]
modified_options[:networks].map! { |id| { :uuid => id } }
end
data = service.create_server(name, image_id, flavor_id, 1, 1, modified_options)
merge_attributes(data.body['server'])
true
end
# Updates server
# This will update :name, :accessIPv4, and :accessIPv6 attributes.
# @note If you edit the server name, the server host name does not change. Also, server names are not guaranteed to be unique.
# @return true if update has started updating
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ServerUpdate.html
#
# * State Transition
# * ACTIVE -> ACTIVE
def update
requires :identity
options = {
'name' => name,
'accessIPv4' => ipv4_address,
'accessIPv6' => ipv6_address
}
data = service.update_server(identity, options)
merge_attributes(data.body['server'])
true
end
# Destroy the server
# @return [Boolean] returns true if server has started deleting
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Delete_Server-d1e2883.html
#
# * Status Transition:
# * ACTIVE -> DELETED
# * ERROR -> DELETED
def destroy
requires :identity
service.delete_server(identity)
true
end
# Server flavor
# @return [Fog::Compute::RackspaceV2::Flavor] server flavor
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
def flavor
requires :flavor_id
@flavor ||= service.flavors.get(flavor_id)
end
# Server image
# @return [Fog::Compute::RackspaceV2::Image] server image
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
def image
requires :image_id
@image ||= service.images.get(image_id)
end
# Creates Image from server. Once complete, a new image is available that you can use to rebuild or create servers.
# @param name [String] name of image to create
# @param options [Hash]:
# @option options [Hash<String, String>] metadata hash of containing metadata key value pairs.
# @return [Fog::ComputeRackspaceV2::Image] image being created
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Create_Image-d1e4655.html
#
# * State Transition:
# * SAVING -> ACTIVE
# * SAVING -> ERROR (on error)
def create_image(name, options = {})
requires :identity
response = service.create_image(identity, name, options)
begin
image_id = response.headers["Location"].match(/\/([^\/]+$)/)[1]
Fog::Compute::RackspaceV2::Image.new(:collection => service.images, :service => service, :id => image_id)
rescue
nil
end
end
# Attached Cloud Block Volumes
# @return [Fog::Compute::RackspaceV2::Attachments] attached Cloud Block Volumes
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/List_Volume_Attachments.html
def attachments
@attachments ||= begin
Fog::Compute::RackspaceV2::Attachments.new({
:service => service,
:server => self
})
end
end
# Attaches Cloud Block Volume
# @param [Fog::Rackspace::BlockStorage::Volume, String] volume object or the volume id of volume to mount
# @param [String] device name of the device /dev/xvd[a-p] (optional)
# @return [Fog::Compute::RackspaceV2::Attachment] resulting attachment object
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Attach_Volume_to_Server.html
def attach_volume(volume, device=nil)
requires :identity
volume_id = volume.is_a?(String) ? volume : volume.id
attachments.create(:server_id => identity, :volume_id => volume_id, :device => device)
end
# Server's private IPv4 address
# @return [String] private IPv4 address
def private_ip_address
addresses['private'].select{|a| a["version"] == 4}[0]["addr"] rescue ''
end
# Server's public IPv4 address
# @return [String] public IPv4 address
def public_ip_address
ipv4_address
end
# Is server is in ready state
# @param [String] ready_state By default state is ACTIVE
# @param [Array,String] error_states By default state is ERROR
# @return [Boolean] returns true if server is in a ready state
# @raise [Fog::Compute::RackspaceV2::InvalidServerStateException] if server state is an error state
def ready?(ready_state = ACTIVE, error_states=[ERROR])
if error_states
error_states = Array(error_states)
raise InvalidServerStateException.new(ready_state, state) if error_states.include?(state)
end
state == ready_state
end
# Reboot server
# @param [String<SOFT, HARD>] type 'SOFT' will do a soft reboot. 'HARD' will do a hard reboot.
# @return [Boolean] returns true if server is being rebooted
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Reboot_Server-d1e3371.html
#
# * State transition:
# * ACTIVE -> REBOOT -> ACTIVE (soft reboot)
# * ACTIVE -> HARD_REBOOT -> ACTIVE (hard reboot)
def reboot(type = 'SOFT')
requires :identity
service.reboot_server(identity, type)
self.state = type == 'SOFT' ? REBOOT : HARD_REBOOT
true
end
# Rebuild removes all data on the server and replaces it with the specified image. The id and all IP addresses remain the same.
# @param [String] image_id image to use for rebuild
# @return [Boolean] returns true if rebuild is in process
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Rebuild_Server-d1e3538.html
#
# * Status Transition:
# * ACTIVE -> REBUILD -> ACTIVE
# * ACTIVE -> REBUILD -> ERROR (on error)
def rebuild(image_id, options={})
requires :identity
service.rebuild_server(identity, image_id, options)
self.state = REBUILD
true
end
# Resize existing server to a different flavor, in essence, scaling the server up or down. The original server is saved for a period of time to allow rollback if there is a problem. All resizes should be tested and explicitly confirmed, at which time the original server is removed. All resizes are automatically confirmed after 24 hours if they are not confirmed or reverted.
# @param [String] flavor_id to resize
# @return [Boolean] returns true if resize is in process
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @note All resizes are automatically confirmed after 24 hours if you do not explicitly confirm or revert the resize.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Resize_Server-d1e3707.html
# @see #confirm_resize
# @see #revert_resize
#
# * Status Transition:
# * ACTIVE -> QUEUE_RESIZE -> PREP_RESIZE -> VERIFY_RESIZE
# * ACTIVE -> QUEUE_RESIZE -> ACTIVE (on error)
def resize(flavor_id)
requires :identity
service.resize_server(identity, flavor_id)
self.state = RESIZE
true
end
# Confirms server resize operation
# @return [Boolean] returns true if resize has been confirmed
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @note All resizes are automatically confirmed after 24 hours if you do not explicitly confirm or revert the resize.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Confirm_Resized_Server-d1e3868.html
# @see #resize
#
# * Status Transition:
# * VERIFY_RESIZE -> ACTIVE
# * VERIFY_RESIZE -> ERROR (on error)å
def confirm_resize
requires :identity
service.confirm_resize_server(identity)
true
end
# Reverts server resize operation
# @return [Boolean] returns true if resize is being reverted
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @note All resizes are automatically confirmed after 24 hours if you do not explicitly confirm or revert the resize.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Revert_Resized_Server-d1e4024.html
# @see #resize
#
# * Status Transition:
# * VERIFY_RESIZE -> ACTIVE
# * VERIFY_RESIZE -> ERROR (on error)
def revert_resize
requires :identity
service.revert_resize_server(identity)
true
end
# Place existing server into rescue mode, allowing for offline editing of configuration. The original server's disk is attached to a new instance of the same base image for a period of time to facilitate working within rescue mode. The original server will be automatically restored after 90 minutes.
# @return [Boolean] returns true if call to put server in rescue mode reports success
# @raise [Fog::Rackspace::Errors::NotFound] - HTTP 404
# @raise [Fog::Rackspace::Errors::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::Errors::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::Errors::ServiceError]
# @note Rescue mode is only guaranteed to be active for 90 minutes.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/rescue_mode.html
# @see #unrescue
#
# * Status Transition:
# * ACTIVE -> PREP_RESCUE -> RESCUE
def rescue
requires :identity
data = service.rescue_server(identity)
merge_attributes(data.body)
true
end
# Remove existing server from rescue mode.
# @return [Boolean] returns true if call to remove server from rescue mode reports success
# @raise [Fog::Rackspace::Errors::NotFound] - HTTP 404
# @raise [Fog::Rackspace::Errors::BadRequest] - HTTP 400
# @raise [Fog::Rackspace::Errors::InternalServerError] - HTTP 500
# @raise [Fog::Rackspace::Errors::ServiceError]
# @note Rescue mode is only guaranteed to be active for 90 minutes.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/exit_rescue_mode.html
# @see #rescue
#
# * Status Transition:
# * PREP_UNRESCUE -> ACTIVE
def unrescue
requires :identity
service.unrescue_server(identity)
self.state = ACTIVE
true
end
# Change admin password
# @param [String] password The administrator password.
# @return [Boolean] returns true if operation was scheduled
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @note Though Rackspace does not enforce complexity requirements for the password, the operating system might. If the password is not complex enough, the server might enter an ERROR state.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Change_Password-d1e3234.html
#
# * Status Transition:
# * ACTIVE -> PASSWORD -> ACTIVE
# * ACTIVE -> PASSWORD -> ERROR (on error)
def change_admin_password(password)
requires :identity
service.change_server_password(identity, password)
self.state = PASSWORD
self.password = password
true
end
# Setup server for SSH access
# @see Servers#bootstrap
def setup(credentials = {})
requires :ssh_ip_address, :identity, :public_key, :username
retried_disconnect = false
commands = [
%{mkdir .ssh},
%{echo "#{public_key}" >> ~/.ssh/authorized_keys},
password_lock,
%{echo "#{Fog::JSON.encode(attributes)}" >> ~/attributes.json},
%{echo "#{Fog::JSON.encode(metadata)}" >> ~/metadata.json}
]
commands.compact
self.password = nil if password_lock
Fog::SSH.new(ssh_ip_address, username, credentials).run(commands)
rescue Errno::ECONNREFUSED
sleep(1)
retry
# Ubuntu 12.04 images seem to be disconnecting during the ssh setup process.
# This rescue block is an effort to address that issue.
rescue Net::SSH::Disconnect
unless retried_disconnect
retried_disconnect = true
sleep(1)
retry
end
end
def virtual_interfaces
@virtual_interfaces ||= Fog::Compute::RackspaceV2::VirtualInterfaces.new :server => self, :service => service
end
private
def adminPass=(new_admin_pass)
self.password = new_admin_pass
end
def password_lock
"passwd -l #{username}" unless attributes[:no_passwd_lock]
end
def user_data_encoded
self.user_data.nil? ? nil : [self.user_data].pack('m')
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,64 @@
require 'fog/core/collection'
require 'fog/rackspace/models/compute_v2/server'
module Fog
module Compute
class RackspaceV2
class Servers < Fog::Collection
model Fog::Compute::RackspaceV2::Server
# Returns list of servers
# @return [Fog::Compute::RackspaceV2::Servers] Retrieves a list servers.
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @note Fog's current implementation only returns 1000 servers
# @note The filter parameter on the method is just to maintain compatability with other providers that support filtering.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/List_Servers-d1e2078.html
def all(filters = {})
data = service.list_servers.body['servers']
load(data)
end
# Creates a new server and populates ssh keys
# @return [Fog::Compute::RackspaceV2::Server]
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @note This method is compatible with Cloud Servers utlizing RackConnect ***if and only if***
# provided the attribute "no_passwd_lock" set to *true*.
# @example
# service.servers.bootstrap :name => 'bootstrap-server',
# :flavor_id => service.flavors.first.id,
# :image_id => service.images.find {|img| img.name =~ /Ubuntu/}.id,
# :public_key_path => '~/.ssh/fog_rsa.pub',
# :private_key_path => '~/.ssh/fog_rsa'
#
# @raise [Fog::Compute::RackspaceV2::InvalidServerStateException] if server state is an error state
def bootstrap(new_attributes = {})
server = create(new_attributes)
server.wait_for { ready? && !public_ip_address.empty? }
server.setup(:password => server.password)
server
end
# Retrieves server
# @param [String] server_id for server to be returned
# @return [Fog::Compute::RackspaceV2:Server]
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Get_Server_Details-d1e2623.html
def get(server_id)
data = service.get_server(server_id).body['server']
new(data)
rescue Fog::Compute::RackspaceV2::NotFound
nil
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,85 @@
require 'fog/core/collection'
require 'fog/rackspace/models/compute_v2/virtual_interface'
module Fog
module Compute
class RackspaceV2
class VirtualInterface < Fog::Model
# @!attribute [r] id
# @return [String] The virtual interface id
identity :id
# @!attribute [r] mac_address
# @return [String] The Media Access Control (MAC) address for the virtual interface.
# A MAC address is a unique identifier assigned to network interfaces for communications on the physical network segment.
attribute :mac_address
# @!attribute [r] ip_addresses
# @return [Array<Hash>] returns an array of hashes containing information about allocated ip addresses and their associated networks
# @example
# [
# {
# "address": "2001:4800:7810:0512:d87b:9cbc:ff04:850c",
# "network_id": "ba122b32-dbcc-4c21-836e-b701996baeb3",
# "network_label": "public"
# },
# {
# "address": "64.49.226.149",
# "network_id": "ba122b32-dbcc-4c21-836e-b701996baeb3",
# "network_label": "public"
# }
# ]
attribute :ip_addresses
# Saves the virtual interface.
# This method can only create a virtual interface. Attempting to update interface will result an exception
# @return [Boolean] true if virtual interface has been saved
def save(attributes = {})
if persisted?
raise Fog::Errors::Error.new("This virtual interface has already been created and it cannot be updated")
else
create
end
true
end
# Creates Virtual interface for server
# * requires attributes: :network
# @return [Boolean] returns true if virtual network interface is being created
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @example To create a virtual interface;
# my_server.virtual_interfaces.create :network => my_network
# @see http://docs.rackspace.com/servers/api/v2/cn-devguide/content/api_create_virtual_interface.html
def create
data = service.create_virtual_interface(server_id, network_id)
merge_attributes(data.body['virtual_interfaces'].first)
end
# Destroy the virtual interface
# @return [Boolean] returns true if virtual interface has been destroyed
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cn-devguide/content/delete_virt_interface_api.html
def destroy
service.delete_virtual_interface(server_id, id)
true
end
private
def server_id
attributes[:server].is_a?(Server) ? attributes[:server].id : attributes[:server]
end
def network_id
attributes[:network].is_a?(Network) ? attributes[:network].id : attributes[:network]
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,46 @@
require 'fog/core/collection'
require 'fog/rackspace/models/compute_v2/virtual_interface'
require 'fog/rackspace/models/compute_v2/server'
module Fog
module Compute
class RackspaceV2
class VirtualInterfaces < Fog::Collection
model Fog::Compute::RackspaceV2::VirtualInterface
attr_reader :server
def server=(obj)
if obj.is_a?(Server)
@server = obj
else
@server = Fog::Compute::RackspaceV2::Server.new :id => obj, :service => service
end
end
# Returns list of virtual interfaces for a server
# @return [Fog::Compute::RackspaceV2::Servers] Retrieves a list virtual interfaces for server.
# @raise [Fog::Compute::RackspaceV2::NotFound] - HTTP 404
# @raise [Fog::Compute::RackspaceV2::BadRequest] - HTTP 400
# @raise [Fog::Compute::RackspaceV2::InternalServerError] - HTTP 500
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @note Fog's current implementation only returns 1000 servers
# @note The filter parameter on the method is just to maintain compatability with other providers that support filtering.
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/List_Servers-d1e2078.html
# @see Fog::Compute::RackspaceV2::Server#virtual_interfaces
def all
raise "Please access this collection via Server#virtual_interfaces" unless self.server
data = service.list_virtual_interfaces(server.id).body['virtual_interfaces']
objects = load(data)
objects.each {|obj| obj.attributes[:server] = self.server}
objects
end
def new(attributes = {})
super({ :server => server }.merge(attributes))
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,43 @@
require 'fog/core/model'
module Fog
module Rackspace
class Databases
class Database < Fog::Model
identity :name
attribute :character_set
attribute :collate
def save
requires :identity, :instance
service.create_database(instance.identity, identity, :character_set => character_set, :collate => collate)
true
end
def destroy
requires :identity, :instance
service.delete_database(instance.identity, identity)
true
end
def grant_access_for(user)
requires :identity, :instance
service.grant_user_access(instance.identity, user, name)
end
def revoke_access_for(user)
requires :identity, :instance
service.revoke_user_access(instance.identity, user, name)
end
private
def instance
collection.instance
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,30 @@
require 'fog/core/collection'
require 'fog/rackspace/models/databases/database'
module Fog
module Rackspace
class Databases
class Databases < Fog::Collection
model Fog::Rackspace::Databases::Database
attr_accessor :instance
def all
load(retrieve_databases)
end
def get(database_name)
data = retrieve_databases.find { |database| database['name'] == database_name }
data && new(data)
end
private
def retrieve_databases
requires :instance
data = service.list_databases(instance.id).body['databases']
end
end
end
end
end

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше