Permalink
Browse files

Merge pull request #1452 from rackspace/server_metadata

Rackspace Server/Image metadata operations
  • Loading branch information...
2 parents 44e9491 + 9d72ff3 commit a8d159f375479c96e804ad2bff38faae5fa68859 @bradgignac bradgignac committed Jan 9, 2013
@@ -104,7 +104,7 @@ def identity(name, options = {})
end
def ignore_attributes(*args)
- @ignored_attributes = args
+ @ignored_attributes = args.collect {|attr| attr.to_s }
end
def ignored_attributes
@@ -54,6 +54,13 @@ class BadRequest < Fog::Rackspace::Errors::BadRequest; end
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 @@ class Image < Fog::Model
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 @@ class Server < Fog::Compute::Server
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 @@ class Server < Fog::Compute::Server
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 @@ def create
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
Oops, something went wrong.

0 comments on commit a8d159f

Please sign in to comment.