Skip to content

Commit

Permalink
[aws|storage] Add bucket lifecycle / object expiration requests.
Browse files Browse the repository at this point in the history
  • Loading branch information
pweldon committed Jan 19, 2012
1 parent 5f44609 commit 0c61fa5
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 0 deletions.
32 changes: 32 additions & 0 deletions lib/fog/aws/parsers/storage/get_bucket_lifecycle.rb
@@ -0,0 +1,32 @@
module Fog
module Parsers
module Storage
module AWS

class GetBucketLifecycle < Fog::Parsers::Base

def reset
@rule = {}
@response = { 'Rules' => [] }
end

def end_element(name)
case name
when 'ID', 'Prefix'
@rule[name] = value
when 'Status'
@rule['Enabled'] = value == 'Enabled'
when 'Days'
@rule[name] = value.to_i
when 'Rule'
@response['Rules'] << @rule
@rule = {}
end
end

end

end
end
end
end
30 changes: 30 additions & 0 deletions lib/fog/aws/requests/storage/delete_bucket_lifecycle.rb
@@ -0,0 +1,30 @@
module Fog
module Storage
class AWS
class Real

# Delete lifecycle configuration for a bucket
#
# ==== Parameters
# * bucket_name<~String> - name of bucket to delete lifecycle configuration from
#
# ==== Returns
# * response<~Excon::Response>:
# * status<~Integer> - 204
#
# ==== See Also
# http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketDELETElifecycle.html

def delete_bucket_lifecycle(bucket_name)
request({
:expects => 204,
:headers => {},
:host => "#{bucket_name}.#{@host}",
:method => 'DELETE',
:query => {'lifecycle' => nil}
})
end
end
end
end
end
41 changes: 41 additions & 0 deletions lib/fog/aws/requests/storage/get_bucket_lifecycle.rb
@@ -0,0 +1,41 @@
module Fog
module Storage
class AWS
class Real

require 'fog/aws/parsers/storage/get_bucket_lifecycle'

# Get bucket lifecycle configuration
#
# ==== Parameters
# * bucket_name<~String> - name of bucket to get lifecycle configuration for
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'Rules'<~Array> - object expire rules
# * 'ID'<~String> - Unique identifier for the rule
# * 'Prefix'<~String> - Prefix identifying one or more objects to which the rule applies
# * 'Enabled'<~Boolean> - if rule is currently being applied
# * 'Days'<~Integer> - lifetime, in days, of the objects that are subject to the rule
#
# ==== See Also
# http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETlifecycle.html

def get_bucket_lifecycle(bucket_name)
request({
:expects => 200,
:headers => {},
:host => "#{bucket_name}.#{@host}",
:idempotent => true,
:method => 'GET',
:parser => Fog::Parsers::Storage::AWS::GetBucketLifecycle.new,
:query => {'lifecycle' => nil}
})
end

end
end
end
end

48 changes: 48 additions & 0 deletions lib/fog/aws/requests/storage/put_bucket_lifecycle.rb
@@ -0,0 +1,48 @@
module Fog
module Storage
class AWS
class Real

# Change lifecycle configuration for an S3 bucket
#
# ==== Parameters
# * bucket_name<~String> - name of bucket to set lifecycle configuration for
# * lifecycle<~Hash>:
# * 'Rules'<~Array> - object expire rules
# * 'ID'<~String> - Unique identifier for the rule
# * 'Prefix'<~String> - Prefix identifying one or more objects to which the rule applies
# * 'Enabled'<~Boolean> - if rule is currently being applied
# * 'Days'<~Integer> - lifetime, in days, of the objects that are subject to the rule
# ==== See Also
# http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html

def put_bucket_lifecycle(bucket_name, lifecycle)
builder = Nokogiri::XML::Builder.new do
LifecycleConfiguration {
lifecycle['Rules'].each do |rule|
Rule {
ID rule['ID']
Prefix rule['Prefix']
Status rule['Enabled'] ? 'Enabled' : 'Disabled'
Expiration { Days rule['Days'] }
}
end
}
end

body = builder.to_xml

request({
:body => body,
:expects => 200,
:headers => {'Content-MD5' => Base64.encode64(Digest::MD5.digest(body)).chomp!,
'Content-Type' => 'application/xml'},
:host => "#{bucket_name}.#{@host}",
:method => 'PUT',
:query => {'lifecycle' => nil}
})
end
end
end
end
end
4 changes: 4 additions & 0 deletions lib/fog/aws/storage.rb
Expand Up @@ -19,11 +19,13 @@ class AWS < Fog::Service
request :complete_multipart_upload
request :copy_object
request :delete_bucket
request :delete_bucket_lifecycle
request :delete_bucket_policy
request :delete_bucket_website
request :delete_object
request :get_bucket
request :get_bucket_acl
request :get_bucket_lifecycle
request :get_bucket_location
request :get_bucket_logging
request :get_bucket_object_versions
Expand All @@ -45,6 +47,7 @@ class AWS < Fog::Service
request :post_object_hidden_fields
request :put_bucket
request :put_bucket_acl
request :put_bucket_lifecycle
request :put_bucket_logging
request :put_bucket_policy
request :put_bucket_versioning
Expand Down Expand Up @@ -338,6 +341,7 @@ def signature(params)
for key in (params[:query] || {}).keys.sort
if %w{
acl
lifecycle
location
logging
notification
Expand Down
62 changes: 62 additions & 0 deletions tests/aws/requests/storage/bucket_tests.rb
Expand Up @@ -179,6 +179,68 @@
Fog::Storage[:aws].delete_bucket_website(@aws_bucket_name)
end

tests('bucket lifecycle') do
pending if Fog.mocking?

lifecycle = {'Rules' => [{'ID' => 'test rule', 'Prefix' => '/prefix', 'Enabled' => true, 'Days' => 42}]}
tests('non-existant bucket') do
tests('#put_bucket_lifecycle').returns([404, 'NoSuchBucket']) do
begin
Fog::Storage[:aws].put_bucket_lifecycle('fognonbucket', lifecycle)
rescue Excon::Errors::NotFound => e
[e.response.status, e.response.body.match(%r{<Code>(.*)</Code>})[1]]
end
end
tests('#get_bucket_lifecycle').returns([404, 'NoSuchBucket']) do
begin
Fog::Storage[:aws].get_bucket_lifecycle('fognonbucket')
rescue Excon::Errors::NotFound => e
[e.response.status, e.response.body.match(%r{<Code>(.*)</Code>})[1]]
end
end
tests('#delete_bucket_lifecycle').returns([404, 'NoSuchBucket']) do
begin
Fog::Storage[:aws].delete_bucket_lifecycle('fognonbucket')
rescue Excon::Errors::NotFound => e
[e.response.status, e.response.body.match(%r{<Code>(.*)</Code>})[1]]
end
end
end
tests('no lifecycle') do
tests('#get_bucket_lifecycle').returns([404, 'NoSuchLifecycleConfiguration']) do
begin
Fog::Storage[:aws].get_bucket_lifecycle(@aws_bucket_name)
rescue Excon::Errors::NotFound => e
[e.response.status, e.response.body.match(%r{<Code>(.*)</Code>})[1]]
end
end
tests('#delete_bucket_lifecycle').succeeds do
Fog::Storage[:aws].delete_bucket_lifecycle(@aws_bucket_name)
end
end
tests('create').succeeds do
Fog::Storage[:aws].put_bucket_lifecycle(@aws_bucket_name, lifecycle)
end
tests('read').returns(lifecycle) do
Fog::Storage[:aws].get_bucket_lifecycle(@aws_bucket_name).body
end
lifecycle = { 'Rules' => 5.upto(6).map { |i| {'ID' => "rule\##{i}", 'Prefix' => i.to_s, 'Enabled' => true, 'Days' => i} } }
tests('update').returns(lifecycle) do
Fog::Storage[:aws].put_bucket_lifecycle(@aws_bucket_name, lifecycle)
Fog::Storage[:aws].get_bucket_lifecycle(@aws_bucket_name).body
end
tests('delete').succeeds do
Fog::Storage[:aws].delete_bucket_lifecycle(@aws_bucket_name)
end
tests('read').returns([404, 'NoSuchLifecycleConfiguration']) do
begin
Fog::Storage[:aws].get_bucket_lifecycle(@aws_bucket_name)
rescue Excon::Errors::NotFound => e
[e.response.status, e.response.body.match(%r{<Code>(.*)</Code>})[1]]
end
end
end

tests("#delete_bucket('#{@aws_bucket_name}')").succeeds do
Fog::Storage[:aws].delete_bucket(@aws_bucket_name)
end
Expand Down

0 comments on commit 0c61fa5

Please sign in to comment.