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

Merge pull request #1232 from benton/feature/aws-rds-tags

Amazon RDS tagging
This commit is contained in:
Wesley Beary 2012-11-01 08:21:57 -07:00
commit 9e47230016
10 changed files with 306 additions and 3 deletions

View file

@ -60,6 +60,24 @@ module Fog
connection.snapshots(:server => self)
end
def tags
requires :id
connection.list_tags_for_resource(id).
body['ListTagsForResourceResult']['TagList']
end
def add_tags(new_tags)
requires :id
connection.add_tags_to_resource(id, new_tags)
tags
end
def remove_tags(tag_keys)
requires :id
connection.remove_tags_from_resource(id, tag_keys)
tags
end
def modify(immediately, options)
options[:security_group_names] ||= options['DBSecurityGroups']
params = self.class.new(options).attributes_to_params

View file

@ -0,0 +1,35 @@
module Fog
module Parsers
module AWS
module RDS
# parses an XML-formatted list of resource tags from AWS
class TagListParser < Fog::Parsers::Base
# each tag is modeled as a String pair (2-element Array)
def reset
@this_key = nil
@this_value = nil
@tags = Hash.new
@response = {'ListTagsForResourceResult' => {'TagList' => {}}}
end
def end_element(name)
super
case name
when 'Tag'
@tags[@this_key] = @this_value
@this_key, @this_value = nil, nil
when 'Key'
@this_key = value
when 'Value'
@this_value = value
when 'TagList'
@response['ListTagsForResourceResult']['TagList'] = @tags
end
end
end
end
end
end
end

View file

@ -23,6 +23,10 @@ module Fog
request :describe_db_engine_versions
request :describe_db_reserved_instances
request :add_tags_to_resource
request :list_tags_for_resource
request :remove_tags_from_resource
request :describe_db_snapshots
request :create_db_snapshot
request :delete_db_snapshot
@ -118,6 +122,8 @@ module Fog
end
class Real
attr_reader :region
include Fog::AWS::CredentialFetcher::ConnectionMethods
# Initialize connection to ELB
#
@ -142,8 +148,8 @@ module Fog
setup_credentials(options)
@connection_options = options[:connection_options] || {}
options[:region] ||= 'us-east-1'
@host = options[:host] || "rds.#{options[:region]}.amazonaws.com"
@region = options[:region] || 'us-east-1'
@host = options[:host] || "rds.#{@region}.amazonaws.com"
@path = options[:path] || '/'
@persistent = options[:persistent] || false
@port = options[:port] || 443
@ -151,6 +157,10 @@ module Fog
@connection = Fog::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options)
end
def owner_id
@owner_id ||= Fog::AWS[:rds].security_groups.get('default').owner_id
end
def reload
@connection.reset
end
@ -181,7 +191,7 @@ module Fog
:host => @host,
:path => @path,
:port => @port,
:version => '2012-01-15' #'2011-04-01'
:version => '2012-09-17' #'2011-04-01'
}
)

View file

@ -0,0 +1,46 @@
module Fog
module AWS
class RDS
class Real
# adds tags to a database instance
# http://docs.amazonwebservices.com/AmazonRDS/latest/APIReference/API_AddTagsToResource.html
# ==== Parameters
# * rds_id <~String> - name of the RDS instance whose tags are to be retrieved
# * tags <~Hash> A Hash of (String) key-value pairs
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
def add_tags_to_resource(rds_id, tags)
keys = tags.keys.sort
values = keys.map {|key| tags[key]}
request({
'Action' => 'AddTagsToResource',
'ResourceName' => "arn:aws:rds:#{@region}:#{owner_id}:db:#{rds_id}",
:parser => Fog::Parsers::AWS::RDS::Base.new,
}.merge(Fog::AWS.indexed_param('Tags.member.%d.Key', keys)).
merge(Fog::AWS.indexed_param('Tags.member.%d.Value', values)))
end
end
class Mock
def add_tags_to_resource(rds_id, tags)
response = Excon::Response.new
if server = self.data[:servers][rds_id]
self.data[:tags][rds_id].merge! tags
response.status = 200
response.body = {
"ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id }
}
response
else
raise Fog::AWS::RDS::NotFound.new("DBInstance #{rds_id} not found")
end
end
end
end
end
end

View file

@ -115,6 +115,8 @@ module Fog
response.status = 200
# This values aren't showed at creating time but at available time
self.data[:servers][db_name]["InstanceCreateTime"] = Time.now
self.data[:tags] ||= {}
self.data[:tags][db_name] = {}
response
end

View file

@ -0,0 +1,44 @@
module Fog
module AWS
class RDS
class Real
require 'fog/aws/parsers/rds/tag_list_parser'
# returns a Hash of tags for a database instance
# http://docs.amazonwebservices.com/AmazonRDS/latest/APIReference/API_ListTagsForResource.html
# ==== Parameters
# * rds_id <~String> - name of the RDS instance whose tags are to be retrieved
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
def list_tags_for_resource(rds_id)
request(
'Action' => 'ListTagsForResource',
'ResourceName' => "arn:aws:rds:#{@region}:#{owner_id}:db:#{rds_id}",
:parser => Fog::Parsers::AWS::RDS::TagListParser.new
)
end
end
class Mock
def list_tags_for_resource(rds_id)
response = Excon::Response.new
if server = self.data[:servers][rds_id]
response.status = 200
response.body = {
"ListTagsForResourceResult" =>
{"TagList" => self.data[:tags][rds_id]}
}
response
else
raise Fog::AWS::RDS::NotFound.new("DBInstance #{rds_id} not found")
end
end
end
end
end
end

View file

@ -0,0 +1,44 @@
module Fog
module AWS
class RDS
class Real
# removes tags from a database instance
# http://docs.amazonwebservices.com/AmazonRDS/latest/APIReference/API_RemoveTagsFromResource.html
# ==== Parameters
# * rds_id <~String> - name of the RDS instance whose tags are to be retrieved
# * keys <~Array> A list of String keys for the tags to remove
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
def remove_tags_from_resource(rds_id, keys)
request(
{ 'Action' => 'RemoveTagsFromResource',
'ResourceName' => "arn:aws:rds:#{@region}:#{owner_id}:db:#{rds_id}",
:parser => Fog::Parsers::AWS::RDS::Base.new,
}.merge(Fog::AWS.indexed_param('TagKeys.member.%d', keys))
)
end
end
class Mock
def remove_tags_from_resource(rds_id, keys)
response = Excon::Response.new
if server = self.data[:servers][rds_id]
keys.each {|key| self.data[:tags][rds_id].delete key}
response.status = 200
response.body = {
"ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id }
}
response
else
raise Fog::AWS::RDS::NotFound.new("DBInstance #{rds_id} not found")
end
end
end
end
end
end

View file

@ -0,0 +1,20 @@
Shindo.tests("AWS::RDS | tagging", ['aws', 'rds']) do
@server = Fog::AWS[:rds].servers.create(rds_default_server_params)
Formatador.display_line "Creating RDS instance #{@server.id}"
Formatador.display_line "Waiting for instance #{@server.id} to be ready"
@server.wait_for { ready? }
tags1 = {'key1' => 'val1'}
tags2 = {'key2' => 'val2'}
tests "add and remove tags from a running RDS model" do
returns({}) { @server.tags }
returns(tags1) { @server.add_tags tags1 }
returns(tags1.merge tags2) { @server.add_tags tags2 }
returns(tags2) { @server.remove_tags tags1.keys }
returns(tags2) { @server.tags }
end
@server.destroy
end

View file

@ -223,6 +223,12 @@ class AWS
}
})
LIST_TAGS_FOR_RESOURCE = {
'ListTagsForResourceResult' => {
'TagList' => Fog::Nullable::Hash
}
}
end
end

View file

@ -0,0 +1,78 @@
Shindo.tests('AWS::RDS | tagging requests', ['aws', 'rds']) do
@rds = Fog::AWS[:rds]
@db_instance_id = "fog-test-#{rand(65536).to_s(16)}"
Formatador.display_line "Creating RDS instance #{@db_instance_id}"
@rds.create_db_instance(@db_instance_id, 'AllocatedStorage' => 5,
'DBInstanceClass' => 'db.t1.micro', 'Engine' => 'mysql',
'MasterUsername' => 'foguser', 'MasterUserPassword' => 'fogpassword')
Formatador.display_line "Waiting for instance #{@db_instance_id} to be ready"
@db = @rds.servers.get(@db_instance_id)
@db.wait_for { ready? }
tests('success') do
single_tag = {'key1' => 'value1'}
two_tags = {'key2' => 'value2', 'key3' => 'value3'}
tests("#add_tags_to_resource with a single tag").
formats(AWS::RDS::Formats::BASIC) do
result = @rds.add_tags_to_resource(@db_instance_id, single_tag).body
returns(single_tag) do
@rds.list_tags_for_resource(@db_instance_id).
body['ListTagsForResourceResult']['TagList']
end
result
end
tests("#add_tags_to_resource with a multiple tags").
formats(AWS::RDS::Formats::BASIC) do
result = @rds.add_tags_to_resource(@db_instance_id, two_tags).body
returns(single_tag.merge(two_tags)) do
@rds.list_tags_for_resource(@db_instance_id).
body['ListTagsForResourceResult']['TagList']
end
result
end
tests("#remove_tags_from_resource").formats(AWS::RDS::Formats::BASIC) do
result = @rds.remove_tags_from_resource(
@db_instance_id, single_tag.keys).body
returns(two_tags) do
@rds.list_tags_for_resource(@db_instance_id).
body['ListTagsForResourceResult']['TagList']
end
result
end
tests("#list_tags_for_resource").
formats(AWS::RDS::Formats::LIST_TAGS_FOR_RESOURCE) do
result = @rds.list_tags_for_resource(@db_instance_id).body
returns(two_tags) do
result['ListTagsForResourceResult']['TagList']
end
result
end
end
tests('failure') do
tests "tagging a nonexisting instance" do
raises(Fog::AWS::RDS::NotFound) do
@rds.add_tags_to_resource('doesnexist', {'key1' => 'value1'})
end
end
tests "listing tags for a nonexisting instance" do
raises(Fog::AWS::RDS::NotFound) do
@rds.list_tags_for_resource('doesnexist')
end
end
tests "removing tags for a nonexisting instance" do
raises(Fog::AWS::RDS::NotFound) do
@rds.remove_tags_from_resource('doesnexist', ['key1'])
end
end
end
Formatador.display_line "Destroying DB instance #{@db_instance_id}"
@db.destroy
end