has
's3'
=> (
is
=>
'ro'
,
isa
=>
'AWS::S3'
,
required
=> 1,
);
has
'name'
=> (
is
=>
'ro'
,
isa
=>
'Str'
,
required
=> 1,
);
has
'creation_date'
=> (
is
=>
'ro'
,
isa
=>
'Str'
,
required
=> 0,
);
has
'acl'
=> (
is
=>
'rw'
,
isa
=>
'Str'
,
required
=> 0,
lazy
=> 1,
clearer
=>
'_clear_acl'
,
default
=>
sub
{
my
$self
=
shift
;
my
$type
=
'GetBucketAccessControl'
;
return
$self
->_get_property(
$type
)->response->decoded_content();
},
trigger
=>
sub
{
my
(
$self
,
$new_val
,
$old_val
) =
@_
;
my
%shorts
=
map
{
$_
=>
undef
}
qw(
private public-read public-read-write authenticated-read
)
;
my
%acl
= ();
if
(
$new_val
=~ m{<} ) {
$acl
{acl_xml} =
$new_val
;
}
elsif
(
exists
$shorts
{
$new_val
} ) {
$acl
{acl_short} =
$new_val
;
}
else
{
die
"Attempt to set an invalid value for acl: '$new_val'"
;
}
my
$type
=
'SetBucketAccessControl'
;
my
$req
=
$self
->s3->request(
$type
,
%acl
,
bucket
=>
$self
->name, );
my
$response
=
$req
->request();
return
if
$response
->response->code == 404;
if
(
my
$msg
=
$response
->friendly_error() ) {
die
$msg
;
}
$self
->_clear_acl;
}
);
has
'location_constraint'
=> (
is
=>
'ro'
,
isa
=>
'Str'
,
required
=> 0,
lazy
=> 1,
default
=>
sub
{
my
$self
=
shift
;
my
$type
=
'GetBucketLocationConstraint'
;
my
$response
=
$self
->_get_property(
$type
);
my
$constraint
=
$response
->xpc->findvalue(
'//s3:LocationConstraint'
);
if
(
defined
$constraint
&&
$constraint
eq
''
) {
return
;
}
else
{
return
$constraint
;
}
}
);
has
'policy'
=> (
is
=>
'rw'
,
isa
=>
'Str'
,
required
=> 0,
lazy
=> 1,
clearer
=>
'_clear_policy'
,
default
=>
sub
{
my
$self
=
shift
;
my
$type
=
'GetBucketPolicy'
;
my
$req
=
$self
->s3->request(
$type
,
bucket
=>
$self
->name, );
my
$response
=
$req
->request();
eval
{
$response
->_parse_errors };
if
(
my
$msg
=
$response
->friendly_error() ) {
if
(
$response
->error_code eq
'NoSuchBucketPolicy'
) {
return
''
;
}
else
{
die
$msg
;
}
}
return
$response
->response->decoded_content();
},
trigger
=>
sub
{
my
(
$self
,
$policy
) =
@_
;
my
$type
=
'SetBucketPolicy'
;
my
$req
=
$self
->s3->request(
$type
,
bucket
=>
$self
->name,
policy
=>
$policy
,
);
my
$response
=
$req
->request();
if
(
my
$msg
=
$response
->friendly_error() ) {
die
$msg
;
}
$self
->_clear_policy;
}
);
sub
enable_cloudfront_distribution {
my
(
$s
,
$cloudfront_dist
) =
@_
;
$cloudfront_dist
->isa(
'AWS::CloudFront::Distribution'
)
or
die
"Usage: enable_cloudfront_distribution( <AWS::CloudFront::Distribution object> )"
;
my
$ident
=
$cloudfront_dist
->cf->create_origin_access_identity(
Comment
=>
"Access to s3://"
.
$s
->name, );
$s
->policy(
<<"JSON");
{
"Version":"2008-10-17",
"Id":"PolicyForCloudFrontPrivateContent",
"Statement":[{
"Sid": "Grant a CloudFront Origin Identity access to support private content",
"Effect":"Allow",
"Principal": {
"CanonicalUser":"@{[ $ident->S3CanonicalUserId ]}"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::@{[ $s->name ]}/*"
}
]
}
JSON
}
sub
files {
my
(
$s
,
%args
) =
@_
;
return
AWS::S3::FileIterator->new(
%args
,
bucket
=>
$s
, );
}
sub
file {
my
(
$s
,
$key
) =
@_
;
my
$type
=
'GetFileInfo'
;
my
$parser
=
$s
->_get_property(
$type
,
key
=>
$key
)
or
return
;
my
$res
=
$parser
->response;
confess
"Cannot get file: "
,
$res
->as_string,
" "
unless
$res
->is_success;
return
AWS::S3::File->new(
bucket
=>
$s
,
key
=>
$key
||
undef
,
size
=>
$res
->header(
'content-length'
) || 0,
contenttype
=>
$res
->header(
'content-type'
) ||
'application/octet-stream'
,
etag
=>
$res
->header(
'etag'
) ||
undef
,
lastmodified
=>
$res
->header(
'last-modified'
) ||
undef
,
is_encrypted
=> (
$res
->header(
'x-amz-server-side-encryption'
) ||
''
) eq
'AES256'
? 1 : 0,
);
}
sub
add_file {
my
(
$s
,
%args
) =
@_
;
my
$file
= AWS::S3::File->new(
%args
,
bucket
=>
$s
);
$file
->contents(
$args
{contents} );
return
$file
;
}
sub
delete
{
my
(
$s
) =
@_
;
my
$type
=
'DeleteBucket'
;
my
$req
=
$s
->s3->request(
$type
,
bucket
=>
$s
->name, );
my
$response
=
$req
->request();
if
(
my
$msg
=
$response
->friendly_error() ) {
die
$msg
;
}
return
1;
}
sub
delete_multi {
my
(
$s
,
@keys
) =
@_
;
die
"You can only delete up to 1000 keys at once"
if
@keys
> 1000;
my
$type
=
'DeleteMulti'
;
my
$req
=
$s
->s3->request(
$type
,
bucket
=>
$s
->name,
keys
=> \
@keys
,
);
my
$response
=
$req
->request();
if
(
my
$msg
=
$response
->friendly_error() ) {
die
$msg
;
}
return
1;
}
sub
_get_property {
my
(
$s
,
$type
,
%args
) =
@_
;
my
$req
=
$s
->s3->request(
$type
,
bucket
=>
$s
->name,
%args
);
my
$response
=
$req
->request();
return
if
$response
->response->code == 404;
if
(
my
$msg
=
$response
->friendly_error() ) {
die
$msg
;
}
return
$response
;
}
__PACKAGE__->meta->make_immutable;