Amazon-S3
view release on metacpan or search on metacpan
lib/Amazon/S3/CLI.pm view on Meta::CPAN
if ( $self->get_format eq 'json' ) {
print {*STDOUT} JSON::PP->new->pretty->encode($rsp);
return $SUCCESS;
}
elsif ( $self->get_format eq 'table' && $self->get_ascii_table ) {
my $t = Text::ASCIITable->new( { headingText => sprintf "Deletion Report\nBucket: %s", $bucket_name } );
$t->setCols( 'Versions', 'Delete Markers', 'Multipart Uploads Aborted', 'Total' );
$t->addRow( @{$rsp}{qw(versions_deleted delete_markers_deleted multipart_uploads_aborted total)} );
print {*STDOUT} $t;
return $SUCCESS;
}
foreach (qw(versions_deleted delete_markers_deleted multipart_uploads_aborted total)) {
print {*STDOUT} sprintf "%30s %s\n", $rsp->{$_};
}
return $SUCCESS;
}
########################################################################
sub cmd_add_key {
########################################################################
my ($self) = @_;
my (@args) = $self->get_args;
my ( $bucket_name, $filename, $object_name ) = choose {
# bucket-name filename object-name
return @args
if @args == 3;
# --bucket-name bucket-name filename
return ( @args, $args[1] )
if @args == 2 && !$self->get_bucket_name;
# --bucket-name bucket-name filename object-name
return ( $self->get_bucket_name, @args )
if $self->get_bucket_name && @args == 2;
# --bucket-name bucket-name --key key-name filename
return ( $self->get_bucket_name, $args[0], $self->get_key )
if $self->get_bucket_name && $self->get_key && @args == 1;
return ( $self->get_bucket_name, $args[0], $args[0] )
if $self->get_bucket_name && @args == 1;
die "ERROR: usage add-key --bucket-name bucket-name filename object-name\n";
};
die sprintf "ERROR: file %s does not exist\n", $filename
if !-e $filename;
if ( $object_name =~ m{\A[/.]}xsm ) {
$object_name =~ s{\A[/.]+(.*)$}{$1}xsm;
}
$self->get_logger->debug(
sub {
return Dumper(
[ bucket_name => $bucket_name,
filename => $filename,
object_name => $object_name,
]
);
}
);
my $content_type = $self->get_content_type // guess_content_type($filename);
my $bucket = $self->get_bucket($bucket_name);
$self->get_logger->debug( sub { return Dumper( [ $bucket->head_key($object_name) ] ); } );
$self->get_logger->debug( sub { return Dumper( [ $bucket, $self->get_s3->last_response ] ); } );
$bucket->add_key_filename( $object_name, $filename, { content_type => $content_type } );
return $SUCCESS;
}
########################################################################
sub cmd_list_directory_buckets {
########################################################################
my ($self) = @_;
my $buckets = $self->get_s3->list_directory_buckets();
return $self->_list_buckets($buckets);
}
########################################################################
sub cmd_create_bucket {
########################################################################
my ($self) = @_;
my ($bucket_name) = $self->get_args;
$bucket_name //= $self->get_bucket_name;
if ( $self->get_availability_zone ) {
$self->get_s3->use_express_one_zone;
}
my $response = $self->get_s3->add_bucket(
{ bucket => $bucket_name,
availability_zone => $self->get_availability_zone,
region => $self->get_region,
}
);
return $SUCCESS;
}
########################################################################
sub cmd_copy_key {
########################################################################
my ($self) = @_;
my ( $bucket_name, $key, $new_key ) = $self->get_args;
if ( $self->get_bucket_name ) {
if ( $self->get_key ) {
$key = $self->get_key;
$new_key = $bucket_name;
}
else {
$new_key = $key;
$key = $bucket_name;
$bucket_name = $self->get_bucket_name;
}
}
die "ERROR: usage: copy-key bucket-name key new-key\n"
if !$key || !$bucket_name || !$new_key;
lib/Amazon/S3/CLI.pm view on Meta::CPAN
print {*STDOUT} "Bucket,Region,CreationDate\n";
foreach my $b ( @{$data} ) {
print {*STDOUT} sprintf qq{"%s","%s","%s"\n}, $b->bucket, $b->region, $b->creation_date;
}
return $SUCCESS;
}
########################################################################
sub init {
########################################################################
my ($self) = @_;
my %endpoint = choose {
return ( host => $self->get_host )
if defined $self->get_host;
return ( endpoint_url => $self->get_endpoint_url )
if $self->get_endpoint_url;
return ();
};
$self->set_ascii_table(
eval {
require Text::ASCIITable;
1;
}
);
die "ERROR: --format must be one of json, text or table\n"
if none { $self->get_format eq $_ } qw(json text table);
my %credentials;
my $has_amazon_credentials = eval {
require Amazon::Credentials;
1;
};
if ($has_amazon_credentials) {
$credentials{credentials} = Amazon::Credentials->new(
{ $self->get_profile
? ( profile => $self->get_profile )
: (),
}
);
}
else {
die "ERROR: --profile requires Amazon::Credentials\n"
if $self->get_profile;
$credentials{aws_access_key_id} = $ENV{AWS_ACCESS_KEY_ID};
$credentials{aws_secret_access_key} = $ENV{AWS_SECRET_ACCESS_KEY};
$credentials{token} = $ENV{AWS_SESSION_TOKEN};
}
my $s3 = Amazon::S3->new(
{ %credentials,
debug => $ENV{DEBUG},
raise_error => $TRUE,
region => $self->get_region,
logger => $self->get_logger,
dns_bucket_names => $self->get_dns_bucket_names // $FALSE,
%endpoint,
defined $self->get_secure ? ( secure => $self->get_secure ) : (),
}
);
$self->set_s3($s3);
return;
}
########################################################################
sub confirm {
########################################################################
my ( $self, $prompt ) = @_;
print "$prompt [y/N] ";
my $answer = <STDIN>;
return $FALSE
if !defined $answer;
chomp $answer;
return $answer =~ /\Ay(?:es)?\z/i ? $TRUE : $FALSE;
}
########################################################################
sub guess_content_type {
########################################################################
my ($filename) = @_;
my $has_mmagic = eval { require File::MimeInfo::Magic; 1; };
return 'application/octet-stream'
if !$has_mmagic || !$filename || !-f $filename;
my $content_type = eval { return File::MimeInfo::Magic::mimetype($filename); };
return $content_type
if !$EVAL_ERROR && $content_type;
return 'application/octet-stream';
}
########################################################################
sub main {
########################################################################
my %default_options = (
output => $EMPTY,
region => 'us-east-1',
format => 'text',
);
my @option_specs = qw(
availability-zone=s
bucket-name|b=s
content-type=s
debug
dns-bucket-names
endpoint-url|u=s
force|f
format|F=s
help|h
host|H=s
key|k=s
modified-since|m=s
output|o=s
prefix=s
profile|p=s
range|R=s
region|r=s
secure|s
version-id=s
);
my %commands = (
'add-key' => \&cmd_add_key,
'copy-key' => \&cmd_copy_key,
'create-bucket' => \&cmd_create_bucket,
'delete-key' => \&cmd_delete_key,
'empty-bucket' => \&cmd_empty_bucket,
'get-key' => \&cmd_get_key,
'get-bucket-policy' => \&cmd_get_bucket_policy,
'get-bucket-acl' => \&cmd_get_bucket_acl,
'get-bucket-policy-status' => \&cmd_get_bucket_policy_status,
'list-bucket-keys' => \&cmd_list_bucket_keys,
'list-directory-buckets' => \&cmd_list_directory_buckets,
'list-keys' => 'list-bucket-keys',
'list-object-versions' => \&cmd_list_object_versions,
'remove-bucket' => \&cmd_remove_bucket,
'list-buckets' => \&cmd_list_buckets,
);
return __PACKAGE__->new(
commands => \%commands,
option_specs => \@option_specs,
default_options => \%default_options,
abbreviations => $TRUE,
extra_options => [qw(s3 secure ascii_table)],
)->run;
}
1;
__END__
## no critic
=pod
=encoding utf8
=head1 NAME
Amazon::S3::CLI - command line interface for common S3 operations
=head1 SYNOPSIS
lib/Amazon/S3/CLI.pm view on Meta::CPAN
Lists general-purpose S3 buckets available to the current credentials.
=item B<list-directory-buckets>
amzn-s3-cli list-directory-buckets
Lists S3 Express One Zone directory buckets.
=item B<list-object-versions>
amzn-s3-cli list-object-versions bucket-name [prefix]
Lists object versions in a bucket.
The listing includes the object key, size, last-modified timestamp,
latest-version indicator, and version ID.
=item B<remove-bucket>
amzn-s3-cli remove-bucket bucket-name
Removes a bucket.
The bucket must satisfy normal S3 deletion requirements. Use
C<empty-bucket> first when necessary.
=back
=head2 Options
Most commands accept the bucket name positionally or through
C<--bucket-name>.
Output-producing commands generally support C<text>, C<json>, and
C<table> formats. Table output requires L<Text::ASCIITable>.
Credentials are discovered through L<Amazon::Credentials> when that
module is installed. Otherwise the CLI uses the standard AWS credential
environment variables.
Use C<--endpoint-url> when working with an alternate S3-compatible
service such as LocalStack.
=head1 OPTIONS
=over
=item B<--availability-zone>
Specifies an Availability Zone when creating an S3 Express One Zone
directory bucket.
=item B<--bucket-name>, B<-b>
Specifies the bucket name.
=item B<--content-type>
Specifies the content type used when adding an object.
=item B<--debug>
Enables debug logging.
=item B<--dns-bucket-names>
Enables DNS-style bucket addressing.
=item B<--endpoint-url>, B<-u>
Specifies the complete S3 service endpoint URL.
For example:
--endpoint-url http://localhost:4566
The URL scheme determines whether HTTP or HTTPS is used.
=item B<--force>, B<-f>
Suppresses confirmation prompts for destructive operations.
=item B<--format>, B<-F>
Selects the output format.
text
json
table
The default is C<text>.
Table output requires L<Text::ASCIITable>.
=item B<--help>, B<-h>
Displays command help.
=item B<--host>, B<-H>
Specifies the S3 service host using the legacy host configuration
mechanism.
C<--endpoint-url> is preferred for alternate endpoints.
=item B<--key>, B<-k>
Specifies an object key.
=item B<--modified-since>, B<-m>
Supplies an C<If-Modified-Since> condition to C<get-key>.
=item B<--output>, B<-o>
Specifies where C<get-key> writes its result.
Use C<-> to write object data to standard output.
=item B<--prefix>
Limits object listing commands to keys beginning with the specified
prefix.
( run in 0.448 second using v1.01-cache-2.11-cpan-062aa07a564 )