Merge pull request #1452 from rackspace/server_metadata
Rackspace Server/Image metadata operations
This commit is contained in:
commit
a8d159f375
|
@ -104,7 +104,7 @@ module Fog
|
|||
end
|
||||
|
||||
def ignore_attributes(*args)
|
||||
@ignored_attributes = args
|
||||
@ignored_attributes = args.collect {|attr| attr.to_s }
|
||||
end
|
||||
|
||||
def ignored_attributes
|
||||
|
|
|
@ -54,6 +54,13 @@ module Fog
|
|||
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
|
||||
|
||||
class Mock
|
||||
|
||||
|
|
|
@ -21,9 +21,30 @@ module Fog
|
|||
attribute :progress
|
||||
attribute :minDisk
|
||||
attribute :minRam
|
||||
attribute :metadata
|
||||
attribute :disk_config, :aliases => 'OS-DCF:diskConfig'
|
||||
attribute :links
|
||||
|
||||
ignore_attributes :metadata
|
||||
|
||||
def initialize(attributes={})
|
||||
@connection = attributes[:connection]
|
||||
super
|
||||
end
|
||||
|
||||
def metadata
|
||||
raise "Please save image before accessing metadata" unless identity
|
||||
@metadata ||= begin
|
||||
Fog::Compute::RackspaceV2::Metadata.new({
|
||||
:connection => connection,
|
||||
:parent => self
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
def metadata=(hash={})
|
||||
raise "Please save image before accessing metadata" unless identity
|
||||
metadata.from_hash(hash)
|
||||
end
|
||||
|
||||
def ready?
|
||||
state == ACTIVE
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class RackspaceV2
|
||||
module MetaParent
|
||||
|
||||
def parent
|
||||
@parent
|
||||
end
|
||||
|
||||
def parent=(new_parent)
|
||||
@parent = new_parent
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def metas_to_hash(metas)
|
||||
hash = {}
|
||||
metas.each { |meta| hash[meta.key] = meta.value }
|
||||
hash
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,77 @@
|
|||
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
|
||||
|
||||
def all
|
||||
requires :parent
|
||||
data = connection.list_metadata(collection_name, parent.id).body['metadata']
|
||||
from_hash(data)
|
||||
end
|
||||
|
||||
def get(key)
|
||||
requires :parent
|
||||
data = connection.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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
data.value = value
|
||||
else
|
||||
self << Fog::Compute::RackspaceV2::Metadatum.new(:key => key, :value => value, :connection => connection, :parent => parent)
|
||||
end
|
||||
value
|
||||
end
|
||||
|
||||
def save
|
||||
requires :parent
|
||||
connection.set_metadata(collection_name, parent.id, to_hash)
|
||||
end
|
||||
|
||||
def new(attributes = {})
|
||||
requires :parent
|
||||
super({ :parent => parent }.merge!(attributes))
|
||||
end
|
||||
|
||||
def from_hash(hash)
|
||||
return unless hash
|
||||
metas = []
|
||||
hash.each_pair {|k,v| metas << {:key => k, :value => v} }
|
||||
load(metas)
|
||||
end
|
||||
|
||||
def to_hash
|
||||
h = {}
|
||||
self.each { |datum| h[datum.key] = datum.value }
|
||||
h
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,29 @@
|
|||
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
|
||||
|
||||
def destroy
|
||||
requires :identity
|
||||
connection.delete_metadata_item(collection_name, parent.id, key)
|
||||
true
|
||||
end
|
||||
|
||||
def save
|
||||
requires :identity, :value
|
||||
connection.set_metadata_item(collection_name, parent.id, key, value)
|
||||
true
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,5 @@
|
|||
require 'fog/compute/models/server'
|
||||
require 'fog/rackspace/models/compute_v2/metadata'
|
||||
|
||||
module Fog
|
||||
module Compute
|
||||
|
@ -32,7 +33,6 @@ module Fog
|
|||
attribute :user_id
|
||||
attribute :tenant_id
|
||||
attribute :links
|
||||
attribute :metadata
|
||||
attribute :personality
|
||||
attribute :ipv4_address, :aliases => 'accessIPv4'
|
||||
attribute :ipv6_address, :aliases => 'accessIPv6'
|
||||
|
@ -41,8 +41,29 @@ module Fog
|
|||
attribute :addresses
|
||||
attribute :flavor_id, :aliases => 'flavor', :squash => 'id'
|
||||
attribute :image_id, :aliases => 'image', :squash => 'id'
|
||||
|
||||
attr_reader :password
|
||||
|
||||
ignore_attributes :metadata
|
||||
|
||||
attr_reader :password
|
||||
def initialize(attributes={})
|
||||
@service = attributes[:service]
|
||||
super
|
||||
end
|
||||
|
||||
def metadata
|
||||
raise "Please save server before accessing metadata" unless identity
|
||||
@metadata ||= begin
|
||||
Fog::Compute::RackspaceV2::Metadata.new({
|
||||
:service => service,
|
||||
:parent => self
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
def metadata=(hash={})
|
||||
raise "Please save server before accessing metadata" unless identity
|
||||
metadata.from_hash(hash)
|
||||
end
|
||||
|
||||
def save
|
||||
if persisted?
|
||||
|
@ -58,7 +79,7 @@ module Fog
|
|||
|
||||
options = {}
|
||||
options[:disk_config] = disk_config unless disk_config.nil?
|
||||
options[:metadata] = metadata unless metadata.nil?
|
||||
options[:metadata] = metadata unless @metadata.nil?
|
||||
options[:personality] = personality unless personality.nil?
|
||||
|
||||
data = service.create_server(name, image_id, flavor_id, 1, 1, options)
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class RackspaceV2
|
||||
class Real
|
||||
def delete_metadata_item(collection, obj_id, key)
|
||||
request(
|
||||
:expects => 204,
|
||||
:method => 'DELETE',
|
||||
:path => "/#{collection}/#{obj_id}/metadata/#{key}"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def delete_metadata_item(collection, obj_id, key)
|
||||
raise Fog::Compute::RackspaceV2::NotFound if obj_id == 0
|
||||
|
||||
response = Excon::Response.new
|
||||
response.body = ""
|
||||
response.status = 204
|
||||
response
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class RackspaceV2
|
||||
class Real
|
||||
def get_metadata_item(collection, obj_id, key)
|
||||
request(
|
||||
:expects => 200,
|
||||
:method => 'GET',
|
||||
:path => "/#{collection}/#{obj_id}/metadata/#{key}"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def get_metadata_item(collection, obj_id, key)
|
||||
raise Fog::Compute::RackspaceV2::NotFound if obj_id == 0
|
||||
|
||||
response = Excon::Response.new
|
||||
response.status = 202
|
||||
response.body = {"meta" => {"environment" => "dev"}}
|
||||
response
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class RackspaceV2
|
||||
class Real
|
||||
def list_metadata(collection, obj_id)
|
||||
request(
|
||||
:expects => [200, 203],
|
||||
:method => 'GET',
|
||||
:path => "/#{collection}/#{obj_id}/metadata"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def list_metadata(collection, obj_id)
|
||||
raise Fog::Compute::RackspaceV2::NotFound if obj_id == 0
|
||||
|
||||
response = Excon::Response.new
|
||||
response.status = 202
|
||||
response.body = { "metadata"=>{"tag"=>"database"} }
|
||||
response
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,28 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class RackspaceV2
|
||||
class Real
|
||||
def set_metadata(collection, obj_id, metadata = {})
|
||||
request(
|
||||
:expects => [200, 203],
|
||||
:method => 'PUT',
|
||||
:path => "/#{collection}/#{obj_id}/metadata",
|
||||
:body => Fog::JSON.encode('metadata' => metadata)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class Mock
|
||||
def set_metadata(collection, obj_id, metadata = {})
|
||||
raise Fog::Compute::RackspaceV2::NotFound if obj_id == 0
|
||||
|
||||
response = Excon::Response.new
|
||||
response.status = 202
|
||||
response.body = {"metadata"=>{"environment"=>"dev"}}
|
||||
response
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,27 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class RackspaceV2
|
||||
class Real
|
||||
def set_metadata_item(collection, obj_id, key, value)
|
||||
request(
|
||||
:expects => 200,
|
||||
:method => 'PUT',
|
||||
:path => "/#{collection}/#{obj_id}/metadata/#{key}",
|
||||
:body => Fog::JSON.encode('meta' => { key => value })
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def set_metadata_item(collection, obj_id, key, value)
|
||||
raise Fog::Compute::RackspaceV2::NotFound if obj_id == 0
|
||||
|
||||
response = Excon::Response.new
|
||||
response.status = 202
|
||||
response.body = {"meta" => {key => value}}
|
||||
response
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,27 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class RackspaceV2
|
||||
class Real
|
||||
def update_metadata(collection, obj_id, metadata = {})
|
||||
request(
|
||||
:expects => [200, 203],
|
||||
:method => 'POST',
|
||||
:path => "/#{collection}/#{obj_id}/metadata",
|
||||
:body => Fog::JSON.encode('metadata' => metadata)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def update_metadata(collection, obj_id, metadata = {})
|
||||
raise Fog::Compute::RackspaceV2::NotFound if obj_id == 0
|
||||
|
||||
response = Excon::Response.new
|
||||
response.status = 202
|
||||
response.body = {"metadata" => {"environment" => "dev", "tag" => "database"}}
|
||||
response
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,42 @@
|
|||
Shindo.tests('Fog::Compute::RackspaceV2 | metadata', ['rackspace']) do
|
||||
|
||||
pending if Fog.mocking?
|
||||
|
||||
service = Fog::Compute::RackspaceV2.new
|
||||
test_time = Time.now.to_i.to_s
|
||||
|
||||
tests('success') do
|
||||
begin
|
||||
@server = service.servers.create(:name => "fog_server_#{test_time}", :flavor_id => 2, :image_id => "3afe97b2-26dc-49c5-a2cc-a2fc8d80c001")
|
||||
@server.wait_for(timeout=1500) { ready? }
|
||||
|
||||
tests('server') do
|
||||
collection_tests(@server.metadata, {:key => 'my_key', :value => 'my_value'}) do
|
||||
@server.wait_for { ready? }
|
||||
end
|
||||
end
|
||||
|
||||
tests('image') do
|
||||
image_id = @server.create_image("fog_image_#{test_time}", :metadata => {:my_key => 'my_value'})
|
||||
@image = service.images.get image_id
|
||||
@image.wait_for(timeout = 1500) { ready? }
|
||||
tests("#all").succeeds do
|
||||
pending if Fog.mocking? && !mocks_implemented
|
||||
metadata = @image.metadata.all
|
||||
my_metadata = metadata.select {|datum| datum.key == 'my_key'}
|
||||
returns(1) { my_metadata.size }
|
||||
returns('my_value') {my_metadata[0].value }
|
||||
end
|
||||
|
||||
tests("#get('my_key')").returns('my_value') do
|
||||
pending if Fog.mocking? && !mocks_implemented
|
||||
@image.metadata.get('my_key').value
|
||||
end
|
||||
end
|
||||
|
||||
ensure
|
||||
@image.destroy if @image
|
||||
@server.destroy if @server
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,104 @@
|
|||
Shindo.tests('Fog::Compute::RackspaceV2 | metadata_tests', ['rackspace']) do
|
||||
|
||||
@service = Fog::Compute.new(:provider => 'Rackspace', :version => 'V2')
|
||||
|
||||
tests('success') do
|
||||
begin
|
||||
metadata = {"tag" => "database"}
|
||||
|
||||
unless Fog.mocking?
|
||||
name = "fog-server-metadata-#{Time.now.to_i}"
|
||||
@server = @service.servers.create(:name => name,
|
||||
:flavor_id => 2,
|
||||
:image_id => '3afe97b2-26dc-49c5-a2cc-a2fc8d80c001',
|
||||
:metadata => metadata)
|
||||
@server.wait_for(timeout = 1500) { ready? }
|
||||
|
||||
|
||||
@server_id = @server.id
|
||||
@image_id = @server.create_image(name, :metadata => metadata)
|
||||
@image = @service.images.get @image_id
|
||||
else
|
||||
@image_id = 1
|
||||
@server_id = 1
|
||||
end
|
||||
|
||||
tests("servers") do
|
||||
tests('list_metadata').returns("metadata" => metadata) do
|
||||
@service.list_metadata("servers", @server_id).body
|
||||
end
|
||||
tests('set_metadata').returns("metadata" => {"environment" => "dev"}) do
|
||||
@service.set_metadata("servers", @server_id, {"environment" => "dev"}).body
|
||||
end
|
||||
tests('update_metadata').returns("metadata" => {"environment" => "dev", "tag" => "database"}) do
|
||||
@service.update_metadata("servers", @server_id, {"environment" => "dev", "tag" => "database"}).body
|
||||
end
|
||||
tests('get_metadata_item').returns("meta" => {"environment" => "dev"}) do
|
||||
@service.get_metadata_item("servers", @server_id, "environment").body
|
||||
end
|
||||
tests('set_metadata_item').returns("meta" => {"environment" => "test"}) do
|
||||
@service.set_metadata_item("servers", @server_id, "environment", "test").body
|
||||
end
|
||||
tests('delete_metadata_item').succeeds do
|
||||
@service.delete_metadata_item("servers", @server_id, "environment").body
|
||||
end
|
||||
end
|
||||
|
||||
tests("images") do
|
||||
@image.wait_for(timeout = 1500) { ready? } unless Fog.mocking?
|
||||
|
||||
tests('list_metadata').returns(metadata) do
|
||||
h = @service.list_metadata("images", @image_id).body
|
||||
h["metadata"].reject {|k,v| k.downcase != "tag"} #only look at the metadata we created
|
||||
end
|
||||
tests('set_metadata').returns({"environment" => "dev"}) do
|
||||
h = @service.set_metadata("images", @image_id, {"environment" => "dev"}).body
|
||||
h["metadata"].reject {|k,v| k.downcase != "environment"} #only look at the metadata we created
|
||||
end
|
||||
tests('update_metadata').returns({"environment" => "dev", "tag" => "database"}) do
|
||||
h = @service.update_metadata("images", @image_id, {"environment" => "dev", "tag" => "database"}).body
|
||||
h["metadata"].reject {|k,v| !['environment', 'tag'].include?(k.downcase)} #only look at the metadata we created
|
||||
end
|
||||
tests('get_metadata_item').returns("meta" => {"environment" => "dev"}) do
|
||||
@service.get_metadata_item("images", @image_id, "environment").body
|
||||
end
|
||||
tests('set_metadata_item').returns("meta" => {"environment" => "test"}) do
|
||||
@service.set_metadata_item("images", @image_id, "environment", "test").body
|
||||
end
|
||||
tests('delete_metadata_item').succeeds do
|
||||
@service.delete_metadata_item("images", @image_id, "environment").body
|
||||
end
|
||||
end
|
||||
ensure
|
||||
@image.destroy if @image
|
||||
@server.destroy if @server
|
||||
end
|
||||
end
|
||||
|
||||
tests('failure') do
|
||||
['server', 'image'].each do |collection|
|
||||
tests(collection) do
|
||||
tests('list_metadata').raises(Fog::Compute::RackspaceV2::NotFound) do
|
||||
@service.list_metadata(collection, 0)
|
||||
end
|
||||
tests('set_server_metadata').raises(Fog::Compute::RackspaceV2::NotFound) do
|
||||
@service.set_metadata(collection, 0, {"environment" => "dev"})
|
||||
end
|
||||
tests('update_server_metadata').raises(Fog::Compute::RackspaceV2::NotFound) do
|
||||
@service.update_metadata(collection, 0, {"environment" => "dev", "tag" => "database"})
|
||||
end
|
||||
tests('get_server_metadata_item').raises(Fog::Compute::RackspaceV2::NotFound) do
|
||||
@service.get_metadata_item(collection, 0, "environment")
|
||||
end
|
||||
tests('set_server_metadata_item').raises(Fog::Compute::RackspaceV2::NotFound) do
|
||||
@service.set_metadata_item(collection, 0, "environment", "test")
|
||||
end
|
||||
tests('delete_server_metadata_item').raises(Fog::Compute::RackspaceV2::NotFound) do
|
||||
@service.delete_metadata_item(collection, 0, "environment")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue