package AWS::CLIWrapper; use strict; use warnings; our $VERSION = '0.01'; use JSON; use IPC::Cmd; our $Error = { Message => '', Code => '' }; sub new { my($class, %param) = @_; my @opt = (); for my $k (qw(region profile endpoint_url)) { if (my $v = delete $param{$k}) { push @opt, param2opt($k, $v); } } my $self = bless { opt => \@opt, json => JSON->new, }, $class; return $self; } sub param2opt { my($k, $v) = @_; my @v; $k =~ s/_/-/g; $k = '--'.$k; my $type = ref $v; if (! $type) { push @v, $v; } elsif ($type eq 'ARRAY') { push @v, @$v; } elsif ($type eq 'HASH') { push @v, encode_json($v); } else { push @v, $v; } return($k, @v); } sub json { $_[0]->{json} } sub _execute { my($self, $service, $operation, $param) = @_; my @cmd = ('aws', @{$self->{opt}}, $service, $operation); while (my($k, $v) = each %$param) { push @cmd, param2opt($k, $v); } my($ok, $err, $buf, $stdout_buf, $stderr_buf) = IPC::Cmd::run( command => \@cmd, timeout => 8, ); if ($ok) { my $json = join "", @$stdout_buf; my($ret) = $self->json->decode_prefix($json); warn sprintf("%s.%s[%s]: %s\n", $service, $operation, 'OK', $json, ) if $ENV{AWSCLI_DEBUG}; return $ret; } else { my $stdout_str = join "", @$stdout_buf; if ($stdout_str && $stdout_str =~ /^{/) { my $json = $stdout_str; warn sprintf("%s.%s[%s]: %s\n", $service, $operation, 'NG', $json, ) if $ENV{AWSCLI_DEBUG}; my($ret) = $self->json->decode_prefix($json); $Error = $ret->{Response}{Errors}{Error}; } else { my $msg = join("", @$buf).": ".$err; warn sprintf("%s.%s[%s]: %s\n", $service, $operation, 'NG', $msg, ) if $ENV{AWSCLI_DEBUG}; $Error = { Message => $msg, Code => 'Unknown' }; } return; } } # aws help | perl -ne 'if (/Available services/../^$/) { s/^\s+\*\s+// or next; chomp; printf "sub %-18s { shift->_execute('"'"'%s'"'"', \@_) }\n", $_, $_}' sub autoscaling { shift->_execute('autoscaling', @_) } sub cloudformation { shift->_execute('cloudformation', @_) } sub cloudwatch { shift->_execute('cloudwatch', @_) } sub directconnect { shift->_execute('directconnect', @_) } sub ec2 { shift->_execute('ec2', @_) } sub elasticbeanstalk { shift->_execute('elasticbeanstalk', @_) } sub elb { shift->_execute('elb', @_) } sub emr { shift->_execute('emr', @_) } sub iam { shift->_execute('iam', @_) } sub rds { shift->_execute('rds', @_) } sub ses { shift->_execute('ses', @_) } sub sns { shift->_execute('sns', @_) } sub sqs { shift->_execute('sqs', @_) } sub sts { shift->_execute('sts', @_) } 1; __END__ =encoding utf-8 =head1 NAME AWS::CLIWrapper - Wrapper module for aws-cli =head1 SYNOPSIS use AWS::CLIWrapper; my $aws = AWS::CLIWrapper->new( region => 'us-west-1', ); my $res = $aws->ec2('describe-instances', { instance_ids => ['i-XXXXX', 'i-YYYYY'], }); if ($res) { for my $rs ( @{ $res->{reservationSet} }) { for my $is (@{ $rs->{instancesSet} }) { print $is->{instanceId},"\n"; } } } else { warn $AWS::CLIWrapper::Error->{Code}; warn $AWS::CLIWrapper::Error->{Message}; } =head1 DESCRIPTION AWS::CLIWrapper is wrapper module for aws-cli. AWS::CLIWrapper is a just wrapper module, so you can do everything what you can do with aws-cli. =head1 METHODS =over 4 =item B($param:HashRef) Constructor of AWS::CLIWrapper. Acceptable param are: region region_name:Str profile profile_name:Str endpoint_url endpoint_url:Str =item B($operation:Str, $param:HashRef) =item B($operation:Str, $param:HashRef) =item B($operation:Str, $param:HashRef) =item B($operation:Str, $param:HashRef) =item B($operation:Str, $param:HashRef) =item B($operation:Str, $param:HashRef) =item B($operation:Str, $param:HashRef) =item B($operation:Str, $param:HashRef) =item B($operation:Str, $param:HashRef) =item B($operation:Str, $param:HashRef) =item B($operation:Str, $param:HashRef) =item B($operation:Str, $param:HashRef) =item B($operation:Str, $param:HashRef) =item B($operation:Str, $param:HashRef) 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. =back =head1 ENVIRONMENT =over 4 =item AWS_CONFIG_FILE =item AWS_ACCESS_KEY_ID =item AWS_SECRET_ACCESS_KEY =item AWS_DEFAULT_REGION See documents of aws-cli. =back =head1 AUTHOR HIROSE Masaaki Ehirose31 _at_ gmail.comE =head1 REPOSITORY L git clone git://github.com/hirose31/AWS-CLIWrapper.git patches and collaborators are welcome. =head1 SEE ALSO L, L, L, =head1 LICENSE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut # for Emacsen # Local Variables: # mode: cperl # cperl-indent-level: 4 # indent-tabs-mode: nil # coding: utf-8 # End: # vi: set ts=4 sw=4 sts=0 :