AWS-CLIWrapper
view release on metacpan or search on metacpan
1.09 2015-10-02
[IMPROVEMENTS]
- Support ec2 wait (PR #9 by @negachov)
1.08 2015-08-19
[IMPROVEMENTS]
- write stdout/stderr message in debug mode (PR #8 by @limitusus)
1.07 2015-07-21
[IMPROVEMENTS]
- Don't execute aws command in load phase
1.06 2014-11-25
[IMPROVEMENTS]
- s3 OPERATION can take --include or --exclude option multiple times
1.05 2014-09-29
[DOCUMENTATION]
- Added LFMF details! (PR #7)
1.04 2014-08-21
- awscli >= 0.14.0 requires upper-case parameters "Key",
"Values", "Value", "Name" in such --filter. But < 1.14.0
requires lower-case parameters "key", "values", "value",
"name". So AWS::CLIWrapper converts upper/lower-case by
version of awscli.
- awscli >= 0.14.0 requires --count pramter in ec2
run-instances, but < 0.14.0 requires --min-count and
--max-count. So AWS::CLIWrapper converts these parameters by
version of awscli
- awscli >= 0.15.0 changed "s3" to "s3api" and "s3" became
another command... So AWS::CLIWrapper calls "s3api"
internally instead of "s3" if awscli >= 0.15.0 and
subcommand seems to old "s3"'s one(--list-buckets,
--put-object and so on), and calls "s3" instead of "s3api"
if awscli < 0.15.0.
- I gave up to work around incompatible changes in type of
returned data structure. For example, awscli 1.0.0
"elb describe-load-balancers" returns hash, on the other
hand, awscli 0.9.3 returns list. Please upgrade awscli
carefully.
0.09 2013-09-02
* Update document on nofork and timeout (thanks @mschrader)
* Add some methods for aws-cli/0.16.0
0.08 2013-07-05
* Potential 'nofork' option to allow calling IPC::Cmd::run vs. run_forked (issue #1, thanks @mschrader)
0.07 2013-06-19
* Add "output_file" key name of parameter for aws s3 get-object
* Enable to specify timeout before aborting "aws" command
0.06 2013-06-12
* Add some methods for aws-cli/0.12.0
* Fix died when failed to parse result as JSON (aws s3)
0.05 2013-05-01
* Add some methods for latest awscli (0.9.2)
0.04 2013-04-30
* Adjust $Error for incompatible changes of aws-cli/botocore
lib/AWS/CLIWrapper.pm view on Meta::CPAN
# if ($type && $type eq 'HASH') {
# for my $hk (keys %$v) {
# if ($hk =~ /^(?:Key|Name|Values|Values)$/) {
# $v->{lc($hk)} = delete $v->{$hk};
# }
# }
# }
# return $v;
# }
# Drop support < 0.14.0 for preventing execute aws command in loading this module
*_compat_kv = *_compat_kv_uc;
sub json { $_[0]->{json} }
sub _execute {
my $self = shift;
my $service = shift;
my $operation = shift;
my @cmd = ($self->awscli_path, @{$self->{opt}}, $service, $operation);
if ($service eq 'ec2' && $operation eq 'wait') {
lib/AWS/CLIWrapper.pm view on Meta::CPAN
}
}
sub _run {
my ($self, $opt, $cmd) = @_;
my $ret;
if (exists $opt->{'nofork'} && $opt->{'nofork'}) {
# better for perl debugger
my($ok, $err, $buf, $stdout_buf, $stderr_buf) = IPC::Cmd::run(
command => join(' ', @$cmd),
timeout => $opt->{timeout} || $self->{timeout},
);
$ret->{stdout} = join "", @$stdout_buf;
$ret->{err_msg} = (defined $err ? "$err\n" : "") . join "", @$stderr_buf;
if ($ok) {
$ret->{exit_code} = 0;
$ret->{timeout} = 0;
} else {
$ret->{exit_code} = 2;
$ret->{timeout} = 1 if defined $err && $err =~ /^IPC::Cmd::TimeOut:/;
lib/AWS/CLIWrapper.pm view on Meta::CPAN
=item B<workspaces>($operation:Str, $param:HashRef, %opt:Hash)
=item B<workspaces_web>($operation:Str, $param:HashRef, %opt:Hash)
=item B<xray>($operation:Str, $param:HashRef, %opt:Hash)
AWS::CLIWrapper provides methods same as services of aws-cli. Please refer to `aws help`.
First arg "operation" is same as operation of aws-cli. Please refer to `aws SERVICE help`.
Second arg "param" is same as command line option of aws-cli.
Please refer to `aws SERVICE OPERATION help`.
Key of param is string that trimmed leading "--" and replaced "-" to "_" for command line option (--instance-ids -> instance_ids).
Value of param is SCALAR or ARRAYREF or HASHREF.
You can specify C<(boolean)> parameter by C<$AWS::CLIWrapper::true> or C<$AWS::CLIWrapper::false>.
my $res = $aws->ec2('assign-private-ip-addresses', {
network_interface_id => $eni_id,
private_ip_addresses => [ $private_ip_1, $private_ip_2 ],
allow_reassignment => $AWS::CLIWrapper::true,
})
lib/AWS/CLIWrapper.pm view on Meta::CPAN
Special case: s3 OPERATION can take --include and --exclude option multiple times. For example "aws s3 sync --exclude 'foo' --exclude 'bar' LocalPath s3://S3Path", Pass ARRAYREF as value of C<include> or C<exclude> in this case:
my $res = $aws->s3('sync', ['LocalPath', 's3://S3Path'], {
exclude => ['foo', 'bar'],
})
Third arg "opt" is optional. Available key/values are below:
timeout => Int
Maximum time the "aws" command is allowed to run before aborting.
default is 30 seconds, unless overridden with AWS_CLIWRAPPER_TIMEOUT environment variable.
nofork => Int (>0)
Call IPC::Cmd::run vs. IPC::Cmd::run_forked (mostly useful if/when in perl debugger). Note: 'timeout', if used with 'nofork', will merely cause an alarm and return. ie. 'run' will NOT kill the awscli command like 'run_forked' will.
croak_on_error => Int (>0)
When set to a truthy value, this will make AWS::CLIWrapper to croak() with error message when `aws` command exits with non-zero status. Default behavior is to set $AWS::CLIWrapper::Error and return.
catch_error_pattern => RegExp
When defined, this option will enable catching `aws-cli` errors matching this pattern
and retrying `aws-cli` command execution. Environment variable
AWS_CLIWRAPPER_CATCH_ERROR_PATTERN takes precedence over this option, if both
are defined.
Default is undef.
catch_error_retries => Int (>= 0)
When defined, this option will set the number of retries to make when `aws-cli` error
was caught with catch_error_pattern, before giving up. Environment variable
AWS_CLIWRAPPER_CATCH_ERROR_RETRIES takes precedence over this option, if both
are defined.
lib/AWS/CLIWrapper.pm view on Meta::CPAN
=item AWS_CLIWRAPPER_TIMEOUT
If this variable is set, this value will be used instead of default timeout (30 seconds) for every
invocation of `aws-cli` that does not have a timeout value provided in the options argument of the
called function.
=item AWS_CLIWRAPPER_CATCH_ERROR_PATTERN
If this variable is set, AWS::CLIWrapper will retry `aws-cli` execution if stdout output
of failed `aws-cli` command matches the pattern. See L<ERROR HANDLING>.
=item AWS_CLIWRAPPER_CATCH_ERROR_RETRIES
How many times to retry command execution if an error was caught. Default is 3.
=item AWS_CLIWRAPPER_CATCH_ERROR_MIN_DELAY
Minimal delay before retrying command execution if an error was caught, in seconds.
Default is 3.
=item AWS_CLIWRAPPER_CATCH_ERROR_MAX_DELAY
Maximal delay before retrying command execution, in seconds. Default is 10.
=item AWS_CONFIG_FILE
=item AWS_ACCESS_KEY_ID
=item AWS_SECRET_ACCESS_KEY
=item AWS_DEFAULT_REGION
See documents of aws-cli.
t/04_errors.t view on Meta::CPAN
use strict;
use Test::More;
use AWS::CLIWrapper;
# Default error handling
my $aws = AWS::CLIWrapper->new;
if ($aws->awscli_version == 0) {
plan skip_all => 'not found aws command';
} else {
plan tests => 4;
}
my $res = $aws->elbv2();
is $res, undef, "default result is undefined";
# Is this a TODO?
is $AWS::CLIWrapper::Error->{Code}, "Unknown", "default error code match";
my $want_err_msg = qr!exited with code \[\d+\]
stderr:
.*
usage: aws \[options\] <command> <subcommand> \[<subcommand> ...\] \[parameters\]
To see help text, you can run:
aws help
aws <command> help
aws <command> <subcommand> help
!ms;
like $AWS::CLIWrapper::Error->{Message}, $want_err_msg, "default error message match";
# Croaking
my $aws_croak = AWS::CLIWrapper->new(croak_on_error => 1);
eval {
$aws_croak->elbv2();
};
t/06_catch_errors.t view on Meta::CPAN
awscli_path => 't/bin/mock-aws',
nofork => 1,
);
my $tests = eval join "\n", <DATA> or die "$@";
for my $test_name (keys %$tests) {
next if @ARGV and not grep { $_ eq $test_name } @ARGV;
my $test = $tests->{$test_name};
my ($wrapper_args, $env, $command, $subcommand, $cmd_args)
= @$test{qw(wrapper_args env command subcommand cmd_args)};
$env = {} unless $env;
my ($tmp_fh, $tmp_name) = tempfile;
print $tmp_fh $test->{retries} || 1;
close $tmp_fh;
local $ENV{AWS_CLIWRAPPER_TEST_ERROR_COUNTER_FILE} = $tmp_name;
local $ENV{AWS_CLIWRAPPER_TEST_DIE_WITH_ERROR} = $test->{error_to_die_with}
if $test->{error_to_die_with};
local @ENV{keys %$env} = values %$env;
$AWS::CLIWrapper::Error = { Message => '', Code => '' };
my $aws = AWS::CLIWrapper->new(%default_wrapper_args, %{$wrapper_args || {}});
my $res = eval { $aws->$command($subcommand, @{$cmd_args || []}) };
if ($test->{retries} > 0) {
open my $fh, "<", $tmp_name;
my $counter = <$fh>;
close $fh;
is $counter, 0, "$test_name retry counter exhausted";
}
like "$@", $test->{exception}, "$test_name exception";
t/06_catch_errors.t view on Meta::CPAN
is_deeply $res, $test->{want}, "$test_name result";
}
done_testing;
__DATA__
# line 60
{
'no-error' => {
command => 'ecs',
subcommand => 'list-clusters',
error_to_die_with => undef,
error_msg_re => qr{^$},
exception => qr{^$},
want => {
clusterArns => [
"arn:aws:ecs:us-foo-1:123456789:cluster/foo",
"arn:aws:ecs:us-foo-1:123456789:cluster/bar",
"arn:aws:ecs:us-foo-1:123456789:cluster/baz"
],
}
},
'no-croak' => {
command => 'ecs',
subcommand => 'list-clusters',
error_to_die_with => 'uh-oh',
error_msg_re => qr{uh-oh},
exception => qr{^$},
want => undef,
},
'with-croak' => {
wrapper_args => { croak_on_error => 1 },
command => 'ecs',
subcommand => 'list-clusters',
error_to_die_with => 'foobaroo!',
error_msg_re => qr{foobaroo},
exception => qr{foobaroo},
want => undef,
},
'catch-no-croak' => {
env => {
AWS_CLIWRAPPER_CATCH_ERROR_PATTERN => 'FUBAR',
AWS_CLIWRAPPER_CATCH_ERROR_MIN_DELAY => 0,
AWS_CLIWRAPPER_CATCH_ERROR_MAX_DELAY => 0,
},
command => 'ecs',
subcommand => 'list-clusters',
error_to_die_with => 'FUBAR',
retries => 2,
error_msg_re => qr{^$},
exception => qr{^$},
want => {
clusterArns => [
"arn:aws:ecs:us-foo-1:123456789:cluster/foo",
"arn:aws:ecs:us-foo-1:123456789:cluster/bar",
"arn:aws:ecs:us-foo-1:123456789:cluster/baz"
],
}
},
'catch-with-croak' => {
env => {
AWS_CLIWRAPPER_CATCH_ERROR_PATTERN => 'throbbe',
AWS_CLIWRAPPER_CATCH_ERROR_MIN_DELAY => 0,
AWS_CLIWRAPPER_CATCH_ERROR_MAX_DELAY => 0,
},
command => 'ecs',
subcommand => 'list-clusters',
error_to_die_with => 'zong throbbe fung',
retries => 3,
error_msg_re => qr{^$},
exception => qr{^$},
want => {
clusterArns => [
"arn:aws:ecs:us-foo-1:123456789:cluster/foo",
"arn:aws:ecs:us-foo-1:123456789:cluster/bar",
"arn:aws:ecs:us-foo-1:123456789:cluster/baz"
],
t/bin/mock-aws view on Meta::CPAN
}
}
sub version {
print "aws-cli/2.42.4242\n";
exit 0;
}
sub help {
die <<__END__;
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:
aws help
aws <command> help
aws <command> <subcommand> help
aws: error: the following arguments are required: operation
__END__
}
sub ecs_list_clusters {
print <<__END__;
{
"clusterArns": [
( run in 0.583 second using v1.01-cache-2.11-cpan-f56aa216473 )