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:
commit
c08a25404d
12 changed files with 410 additions and 17 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
56
lib/fog/rackspace/models/compute_v2/keypair.rb
Normal file
56
lib/fog/rackspace/models/compute_v2/keypair.rb
Normal 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
|
43
lib/fog/rackspace/models/compute_v2/keypairs.rb
Normal file
43
lib/fog/rackspace/models/compute_v2/keypairs.rb
Normal 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
|
|
@ -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
|
||||
|
|
53
lib/fog/rackspace/requests/compute_v2/create_keypair.rb
Normal file
53
lib/fog/rackspace/requests/compute_v2/create_keypair.rb
Normal 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
|
|
@ -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
|
||||
|
|
36
lib/fog/rackspace/requests/compute_v2/delete_keypair.rb
Normal file
36
lib/fog/rackspace/requests/compute_v2/delete_keypair.rb
Normal 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
|
41
lib/fog/rackspace/requests/compute_v2/get_keypair.rb
Normal file
41
lib/fog/rackspace/requests/compute_v2/get_keypair.rb
Normal 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
|
37
lib/fog/rackspace/requests/compute_v2/list_keypairs.rb
Normal file
37
lib/fog/rackspace/requests/compute_v2/list_keypairs.rb
Normal 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
|
47
tests/rackspace/models/compute_v2/keypairs_tests.rb
Normal file
47
tests/rackspace/models/compute_v2/keypairs_tests.rb
Normal 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
|
55
tests/rackspace/requests/compute_v2/keypair_tests.rb
Normal file
55
tests/rackspace/requests/compute_v2/keypair_tests.rb
Normal 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
|
Loading…
Reference in a new issue