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

Merge pull request #1966 from bartvercammen/rackspace

[rackspace] add keypair support
This commit is contained in:
Kyle Rames 2013-07-26 07:15:31 -07:00
commit c08a25404d
12 changed files with 410 additions and 17 deletions

View file

@ -54,6 +54,8 @@ module Fog
collection :attachments
model :network
collection :networks
model :keypair
collection :keypairs
request_path 'fog/rackspace/requests/compute_v2'
request :list_servers
@ -97,6 +99,11 @@ module Fog
request :create_network
request :delete_network
request :list_keypairs
request :create_keypair
request :delete_keypair
request :get_keypair
class Mock < Fog::Rackspace::Service
include Fog::Rackspace::MockData

View file

@ -8,10 +8,11 @@ module Fog
@@data ||= Hash.new do |hash, key|
hash[key] = begin
#Compute V2
flavor_id = Fog.credentials[:rackspace_flavor_id].to_s ||= Fog::Mock.random_numbers(1)
image_id = Fog.credentials[:rackspace_image_id] ||= Fog::Rackspace::MockData.uuid
flavor_id = Fog.credentials[:rackspace_flavor_id].to_s ||= Fog::Mock.random_numbers(1)
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,
@ -88,6 +89,14 @@ module Fog
'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
@ -106,11 +115,13 @@ module Fog
mock_data = {
#Compute V2
:flavors => Hash.new { |h,k| h[k] = flavor unless k == NOT_FOUND_ID},
:images => Hash.new { |h,k| h[k] = image unless k == NOT_FOUND_ID },
:flavors => Hash.new { |h,k| h[k] = flavor unless k == NOT_FOUND_ID },
:images => Hash.new { |h,k| h[k] = image unless k == NOT_FOUND_ID },
:networks => Hash.new { |h,k| h[k] = network unless k == NOT_FOUND_ID },
:servers => {},
:keys => [],
:keypair => key_pair,
:keypairs => [],
:servers => {},
#Block Storage
:volumes => {},
@ -123,7 +134,7 @@ module Fog
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]

View file

@ -0,0 +1,56 @@
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, public_key)
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

View file

@ -0,0 +1,43 @@
require 'fog/core/collection'
require 'fog/rackspace/models/compute_v2/keypair'
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

View file

@ -51,6 +51,11 @@ module Fog
# @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.
@ -198,11 +203,11 @@ module Fog
options[:disk_config] = disk_config unless disk_config.nil?
options[:metadata] = metadata.to_hash unless @metadata.nil?
options[:personality] = personality unless personality.nil?
options[:keypair] ||= attributes[:keypair]
if options[:networks]
options[:networks].map! { |id| { :uuid => id } }
end
data = service.create_server(name, image_id, flavor_id, 1, 1, options)
merge_attributes(data.body['server'])
true
@ -331,7 +336,7 @@ module Fog
# Server's private IPv4 address
# @return [String] private IPv4 address
def private_ip_address
addresses['private'].select{|a| a["version"] == 4}[0]["addr"]
addresses['private'].select{|a| a["version"] == 4}[0]["addr"] rescue ''
end
# Server's public IPv4 address

View file

@ -0,0 +1,53 @@
module Fog
module Compute
class RackspaceV2
class Real
# Request a new keypair to be created
# @param [String] key_name: unique name of the keypair to create
# @return [Excon::Response] response :
# * body [Hash]: -
# * 'keypair' [Hash]: -
# * 'fingerprint' [String]: unique fingerprint of the keypair
# * 'name' [String]: unique name of the keypair
# * 'private_key' [String]: the private key of the keypair (only available here, at creation time)
# * 'public_key' [String]: the public key of the keypair
# * 'user_id' [String]: the user id
# @raise [Fog::Compute::RackspaceV2::NotFound]
# @raise [Fog::Compute::RackspaceV2::BadRequest]
# @raise [Fog::Compute::RackspaceV2::InternalServerError]
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/CreateKeyPair.html
def create_keypair(key_name, public_key=nil)
data = {
'keypair' => {
'name' => key_name
}
}
request(
:method => 'POST',
:expects => 200,
:path => '/os-keypairs',
:body => Fog::JSON.encode(data)
)
end
end
class Mock
def create_keypair(key_name, public_key=nil)
# 409 response when already existing
raise Fog::Compute::RackspaceV2::ServiceError if not self.data[:keypairs].select { |k| key_name.include? k['keypair']['name'] }.first.nil?
k = self.data[:keypair]
k['name'] = key_name
self.data[:keypairs] << { 'keypair' => k }
response( :status => 200,
:body => { 'keypair' => k } )
end
end
end
end
end

View file

@ -12,12 +12,13 @@ module Fog
# @option options [Hash] metadata key value pairs of server metadata
# @option options [String] OS-DCF:diskConfig The disk configuration value. (AUTO or MANUAL)
# @option options [Hash] personality Hash containing data to inject into the file system of the cloud server instance during server creation.
# @option options [String] keypair Name of the kay-pair to associate with this server.
# @return [Excon::Response] response:
# * body [Hash]:
# * server [Hash]:
# * name [String] - name of server
# * imageRef [String] - id of image used to create server
# * flavorRef [String] - id of flavor used to create server
# * flavorRef [String] - id of flavor used to create server
# * OS-DCF:diskConfig [String] - The disk configuration value.
# * name [String] - name of server
# * metadata [Hash] - Metadata key and value pairs.
@ -43,11 +44,11 @@ module Fog
def create_server(name, image_id, flavor_id, min_count, max_count, options = {})
data = {
'server' => {
'name' => name,
'imageRef' => image_id,
'name' => name,
'imageRef' => image_id,
'flavorRef' => flavor_id,
'minCount' => min_count,
'maxCount' => max_count
'minCount' => min_count,
'maxCount' => max_count
}
}
@ -58,12 +59,13 @@ module Fog
{ :uuid => '00000000-0000-0000-0000-000000000000' },
{ :uuid => '11111111-1111-1111-1111-111111111111' }
]
data['server']['key_name'] = options[:keypair] unless options[:keypair].nil?
request(
:body => Fog::JSON.encode(data),
:body => Fog::JSON.encode(data),
:expects => [202],
:method => 'POST',
:path => "servers"
:method => 'POST',
:path => "servers"
)
end
end

View file

@ -0,0 +1,36 @@
module Fog
module Compute
class RackspaceV2
class Real
# Delete the key specified with key_name
# @param [String] key_name: name of the key to delete
# @return [Excon::Response] response
# @raise [Fog::Compute::RackspaceV2::NotFound]
# @raise [Fog::Compute::RackspaceV2::BadRequest]
# @raise [Fog::Compute::RackspaceV2::InternalServerError]
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/DeleteKeyPair.html
def delete_keypair(key_name)
request(
:method => 'DELETE',
:expects => 202,
:path => "/os-keypairs/#{key_name}"
)
end
end
class Mock
def delete_keypair(key_name)
if self.data[:keypairs].select { |k| key_name.include? k['keypair']['name'] }.empty?
raise Fog::Compute::RackspaceV2::NotFound
else
self.data[:keypairs].reject! { |k| key_name.include? k['keypair']['name'] }
response(:status => 202)
end
end
end
end
end
end

View file

@ -0,0 +1,41 @@
module Fog
module Compute
class RackspaceV2
class Real
# Retreive single keypair details
# @param [String] key_name: name of the key for which to request the details
# @return [Excon::Response] response :
# * body [Hash]: -
# * 'keypair' [Hash]: -
# * 'fingerprint' [String]: unique fingerprint of the keypair
# * 'name' [String]: unique name of the keypair
# * 'public_key' [String]: the public key assigne to the keypair
# @raise [Fog::Compute::RackspaceV2::NotFound]
# @raise [Fog::Compute::RackspaceV2::BadRequest]
# @raise [Fog::Compute::RackspaceV2::InternalServerError]
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ListKeyPairs.html
def get_keypair(key_name)
request(
:method => 'GET',
:expects => 200,
:path => "/os-keypairs/#{key_name}"
)
end
end
class Mock
def get_keypair(key_name)
key = self.data[:keypairs].select { |k| key_name.include? k['keypair']['name'] }.first
if key.nil?
raise Fog::Compute::RackspaceV2::NotFound
end
response(:body => key, :status => 200)
end
end
end
end
end

View file

@ -0,0 +1,37 @@
module Fog
module Compute
class RackspaceV2
class Real
# Returns a list of all key pairs associated with an account.
# @return [Excon::Response] response :
# * body [Hash]: -
# * 'keypairs' [Array]: list of keypairs
# * 'keypair' [Hash]: -
# * 'fingerprint' [String]: unique fingerprint of the keypair
# * 'name' [String]: unique name of the keypair
# * 'public_key' [String]: the public key assigned to the keypair
# @raise [Fog::Compute::RackspaceV2::NotFound]
# @raise [Fog::Compute::RackspaceV2::BadRequest]
# @raise [Fog::Compute::RackspaceV2::InternalServerError]
# @raise [Fog::Compute::RackspaceV2::ServiceError]
# @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ListKeyPairs.html
def list_keypairs
request(
:method => 'GET',
:expects => 200,
:path => '/os-keypairs'
)
end
end
class Mock
def list_keypairs
response( :status => 200,
:body => { 'keypairs' => self.data[:keypairs] })
end
end
end
end
end

View file

@ -0,0 +1,47 @@
Shindo.tests('Fog::Compute::RackspaceV2 | keypairs', ['rackspace']) do
service = Fog::Compute::RackspaceV2.new
name = Fog::Mock.random_letters(32)
key = nil
tests("API access") do
begin
tests("create").succeeds do
key = service.keypairs.create({:name => name})
end
tests("list all").succeeds do
service.keypairs.all
end
tests("get").succeeds do
service.keypairs.get(name)
end
tests("delete").succeeds do
key = nil if service.keypairs.destroy(name)
key == nil
end
tests("get unknown").returns(nil) do
service.keypairs.get(Fog::Mock.random_letters(32))
end
tests("delete unknown").raises(Fog::Compute::RackspaceV2::NotFound) do
service.keypairs.destroy(Fog::Mock.random_letters(32))
end
tests("create again after delete").succeeds do
key = service.keypairs.create({:name => name})
end
tests("create already existing").raises(Fog::Compute::RackspaceV2::ServiceError) do
service.keypairs.create({:name => name})
end
ensure
key.destroy if key
end
end
end

View file

@ -0,0 +1,55 @@
Shindo.tests('Fog::Compute::RackspaceV2 | keypair_tests', ['rackspace']) do
keypair_format = {
'name' => String,
'public_key' => String,
'fingerprint' => String,
}
create_keypair_format = {
'keypair' => keypair_format.merge({
'user_id' => String,
'private_key' => String
})
}
list_keypair_format = {
'keypairs' => [ 'keypair' => keypair_format ]
}
get_keypair_format = {
'keypair' => keypair_format
}
service = Fog::Compute.new(:provider => 'Rackspace', :version => 'V2')
keypair_name = Fog::Mock.random_letters(32)
tests('success') do
tests('#create_keypair').formats(create_keypair_format) do
service.create_keypair(keypair_name).body
end
tests('#list_keypairs').formats(list_keypair_format) do
service.list_keypairs.body
end
tests('#get_keypair').formats(get_keypair_format) do
service.get_keypair(keypair_name).body
end
tests('#delete_keypair') do
service.delete_keypair(keypair_name).body
end
end
unknown_keypair_name = Fog::Mock.random_letters(32)
tests('failure') do
tests('#get_unknown_keypair').raises(Fog::Compute::RackspaceV2::NotFound) do
service.get_keypair(unknown_keypair_name).body
end
tests('#delete_unknown_keypair').raises(Fog::Compute::RackspaceV2::NotFound) do
service.delete_keypair(unknown_keypair_name).body
end
end
end