line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Mojo::Cloudstack; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
37678741
|
use Mojo::Base 'Mojo::UserAgent'; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
14
|
|
4
|
1
|
|
|
1
|
|
251
|
use Mojo::Parameters; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
11
|
|
5
|
1
|
|
|
1
|
|
32
|
use Mojo::URL; |
|
1
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
7
|
|
6
|
1
|
|
|
1
|
|
31
|
use Mojo::UserAgent; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
4
|
|
7
|
1
|
|
|
1
|
|
32
|
use Mojo::JSON 'j'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
63
|
|
8
|
1
|
|
|
1
|
|
6
|
use Mojo::Util 'slurp'; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
56
|
|
9
|
1
|
|
|
1
|
|
6
|
use Mojo::Collection 'c'; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
61
|
|
10
|
1
|
|
|
1
|
|
612
|
use Mojo::Cloudstack::Base; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
10
|
|
11
|
1
|
|
|
1
|
|
600
|
use Mojo::Cloudstack::Api; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
9
|
|
12
|
1
|
|
|
1
|
|
916
|
use Digest::HMAC_SHA1 qw(hmac_sha1 hmac_sha1_hex); |
|
1
|
|
|
|
|
1763
|
|
|
1
|
|
|
|
|
61
|
|
13
|
1
|
|
|
1
|
|
7
|
use MIME::Base64; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
59
|
|
14
|
1
|
|
|
1
|
|
848
|
use URI::Encode 'uri_encode'; |
|
1
|
|
|
|
|
2610
|
|
|
1
|
|
|
|
|
135
|
|
15
|
1
|
|
|
1
|
|
1350
|
use File::HomeDir; |
|
1
|
|
|
|
|
9435
|
|
|
1
|
|
|
|
|
57
|
|
16
|
1
|
|
|
1
|
|
7
|
use Data::Dumper 'Dumper'; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
1538
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
has 'host' => "localhost"; |
19
|
|
|
|
|
|
|
has 'path' => "/client/api"; |
20
|
|
|
|
|
|
|
has 'port' => "8080"; |
21
|
|
|
|
|
|
|
has 'scheme' => "https"; |
22
|
|
|
|
|
|
|
has 'api_key' => ""; |
23
|
|
|
|
|
|
|
has 'secret_key' => ""; |
24
|
|
|
|
|
|
|
has 'responsetypes' => ''; |
25
|
|
|
|
|
|
|
has 'api_cache' => sub { |
26
|
|
|
|
|
|
|
my $self = shift; |
27
|
|
|
|
|
|
|
$self->_load_api_cache; |
28
|
|
|
|
|
|
|
$self->__build_responsetypes; |
29
|
|
|
|
|
|
|
}; |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
our $VERSION = '0.07'; |
32
|
|
|
|
|
|
|
our $AUTOLOAD; |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
chomp(our $user = `whoami`); |
35
|
|
|
|
|
|
|
our $cf = File::HomeDir->users_home($user) . "/.cloudmojo/api.json"; |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
sub _build_request { |
38
|
1
|
|
|
1
|
|
952
|
my ($self, $params) = @_; |
39
|
1
|
|
|
|
|
6
|
my $baseurl = sprintf ("%s://%s:%s%s?", $self->scheme, $self->host, $self->port, $self->path); |
40
|
1
|
|
|
|
|
23
|
$params->{ apiKey } = $self->api_key; |
41
|
1
|
|
|
|
|
7
|
$params->{ response } = 'json'; |
42
|
1
|
|
|
|
|
4
|
my $secret_key = $self->secret_key; |
43
|
|
|
|
|
|
|
|
44
|
1
|
|
|
|
|
8
|
my $req_params = Mojo::Parameters->new(); |
45
|
1
|
|
|
|
|
15
|
foreach my $p (sort keys %$params) { |
46
|
3
|
|
|
|
|
2420
|
$req_params->param($p => uri_encode($params->{ $p })); |
47
|
|
|
|
|
|
|
} |
48
|
1
|
|
|
|
|
1086
|
my $params_str = lc ($req_params->to_string); |
49
|
1
|
|
|
|
|
160
|
my $digest = hmac_sha1($params_str, $secret_key); |
50
|
1
|
|
|
|
|
88
|
my $base64_encoded = encode_base64($digest); |
51
|
1
|
|
|
|
|
2
|
chomp ($base64_encoded); |
52
|
|
|
|
|
|
|
|
53
|
1
|
|
|
|
|
4
|
my $uri_encoded = uri_encode($base64_encoded,1); |
54
|
1
|
|
|
|
|
1131
|
my $url = Mojo::URL->new($baseurl); |
55
|
1
|
|
|
|
|
253
|
$url->query($req_params->to_string); |
56
|
|
|
|
|
|
|
|
57
|
1
|
|
|
|
|
182
|
return $url->to_string . '&signature='.$uri_encoded; |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
sub AUTOLOAD { |
62
|
0
|
|
|
0
|
|
|
my $self = shift; |
63
|
0
|
|
|
|
|
|
(my $command = $AUTOLOAD) =~ s/.*:://; |
64
|
0
|
|
|
|
|
|
my %params = @_; |
65
|
0
|
|
|
|
|
|
$params{command} = $command; |
66
|
0
|
|
|
|
|
|
my $req = $self->_build_request(\%params); |
67
|
0
|
|
|
|
|
|
my $res = $self->post($req)->res; |
68
|
0
|
|
|
|
|
|
my $items = $res->json; |
69
|
|
|
|
|
|
|
#warn Dumper 'ITEMS', $items; |
70
|
0
|
0
|
|
|
|
|
die sprintf("Could not get response for %s\n%s", $req, Dumper($res)) unless $items; |
71
|
0
|
|
|
|
|
|
my $responsetype = (keys %$items)[0]; |
72
|
|
|
|
|
|
|
|
73
|
0
|
0
|
|
|
|
|
if($responsetype =~ /^(login|activate|add|archive|assign|associate|attach|authorize|change|configure|copy|create|delete|deploy|destroy|detach|disable|disassociate|enable|error|expunge|extract|get|list|lock|migrate|query|reboot|recover|register|remove|replace|reset|resize|restart|restore|revert|revoke|scale|start|stop|suspend|update|upload)(.*)(response)$/){ |
74
|
0
|
|
|
|
|
|
my ($otype, $oname, $oresponse) = ($1, $2, $3); |
75
|
0
|
0
|
|
|
|
|
$items->{$responsetype}{_cs} = $self unless $oname eq 'apis'; |
76
|
0
|
0
|
|
|
|
|
if($oname eq 'apis'){ |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
77
|
0
|
|
|
|
|
|
$self->__write_api_cache($items); |
78
|
0
|
|
|
|
|
|
return $items; |
79
|
|
|
|
|
|
|
} elsif($otype eq 'list'){ |
80
|
0
|
0
|
|
|
|
|
if($oname =~ /(s)$/){ |
81
|
0
|
|
|
|
|
|
$oname =~ s/$1$//; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
return c( |
84
|
|
|
|
|
|
|
map { |
85
|
0
|
|
|
|
|
|
$_->{_cs} = $self; |
86
|
0
|
|
|
|
|
|
Mojo::Cloudstack::Base->new('Mojo::Cloudstack::' . ucfirst($oname),$_); |
87
|
0
|
|
|
|
|
|
} @{$items->{$responsetype}{$oname}} |
|
0
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
); |
89
|
|
|
|
|
|
|
} elsif($otype eq 'query'){ |
90
|
0
|
|
|
|
|
|
return Mojo::Cloudstack::Base->new('Mojo::Cloudstack::AsyncJobResult', $items->{$responsetype}); |
91
|
|
|
|
|
|
|
} elsif(exists $items->{$responsetype}{errorcode}){ |
92
|
0
|
|
|
|
|
|
return Mojo::Cloudstack::Base->new('Mojo::Cloudstack::Error', $items->{$responsetype}); |
93
|
|
|
|
|
|
|
} elsif($otype =~ /^log(in|out)$/){ |
94
|
0
|
|
|
|
|
|
return Mojo::Cloudstack::Base->new('Mojo::Cloudstack::' . ucfirst($&), $items->{$responsetype}); |
95
|
|
|
|
|
|
|
} else { |
96
|
|
|
|
|
|
|
return Mojo::Cloudstack::Base->new('Mojo::Cloudstack::' . (exists $items->{$responsetype}{jobid} |
97
|
|
|
|
|
|
|
? 'AsyncJobRequest' |
98
|
0
|
0
|
|
|
|
|
: ucfirst($oname)), $items->{$responsetype}); |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
} else { |
101
|
0
|
|
|
|
|
|
die "unknown response type $responsetype for reqest \n$req"; |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
sub sync { |
107
|
0
|
|
|
0
|
1
|
|
return shift->_load_api_cache(1); |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
sub _load_api_cache { |
111
|
0
|
|
|
0
|
|
|
my ($self, $force) = @_; |
112
|
0
|
0
|
0
|
|
|
|
$self->api_cache($self->__build_api_json($force)) |
|
|
|
0
|
|
|
|
|
113
|
|
|
|
|
|
|
and return $self->api_cache |
114
|
|
|
|
|
|
|
if ($force or (not -f $cf)); |
115
|
|
|
|
|
|
|
#TODO File::ShareDir |
116
|
|
|
|
|
|
|
|
117
|
0
|
0
|
|
|
|
|
$self->api_cache(j(slurp $cf)) if -f $cf; |
118
|
0
|
|
|
|
|
|
return $self->api_cache; |
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
sub __build_responsetypes { |
122
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
123
|
0
|
|
|
|
|
|
my $apis = $self->api_cache; |
124
|
0
|
|
|
|
|
|
my %responsetypes = map { (split(/[A-Z]/,$_->{name},2))[0] => 1 } |
125
|
0
|
|
|
|
|
|
@{ $apis->{listapisresponse}{api} }; |
|
0
|
|
|
|
|
|
|
126
|
0
|
|
|
|
|
|
$responsetypes{error} = 1; |
127
|
0
|
|
|
|
|
|
$self->responsetypes(join('|', sort keys %responsetypes)); |
128
|
0
|
|
|
|
|
|
die $self->responsetypes; |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub __build_api_json { |
132
|
0
|
|
|
0
|
|
|
my ($self, $force) = @_; |
133
|
0
|
|
|
|
|
|
my $apis = $self->listApis; |
134
|
0
|
|
|
|
|
|
$self->__write_api_cache($apis, $force); |
135
|
0
|
|
|
|
|
|
return $apis; |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
sub __write_api_cache { |
139
|
0
|
|
|
0
|
|
|
my($self, $apis, $force) = @_; |
140
|
0
|
|
|
|
|
|
my $cachedir = File::HomeDir->users_home($user) . "/.cloudmojo"; |
141
|
0
|
0
|
|
|
|
|
mkdir $cachedir unless -d $cachedir; |
142
|
0
|
|
|
|
|
|
my $cachefile = "$cachedir/api.json"; |
143
|
0
|
0
|
|
|
|
|
unlink $cachefile if $force; |
144
|
0
|
0
|
|
|
|
|
unless (-f $cachefile){ |
145
|
0
|
|
|
|
|
|
open my $cf, ">$cachefile"; |
146
|
0
|
|
|
|
|
|
print $cf j($apis); |
147
|
0
|
|
|
|
|
|
close $cf; |
148
|
|
|
|
|
|
|
} |
149
|
0
|
|
|
|
|
|
return $apis; |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
1; |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
__END__ |