File Coverage

blib/lib/Net/RackSpace/CloudServers/Server.pm
Criterion Covered Total %
statement 28 67 41.7
branch 0 22 0.0
condition n/a
subroutine 10 15 66.6
pod 5 5 100.0
total 43 109 39.4


line stmt bran cond sub pod time code
1             package Net::RackSpace::CloudServers::Server;
2              
3             BEGIN {
4 2     2   37 $Net::RackSpace::CloudServers::Server::VERSION = '0.14';
5             }
6 2     2   11 use warnings;
  2         3  
  2         43  
7 2     2   9 use strict;
  2         4  
  2         73  
8             our $DEBUG = 0;
9 2     2   11 use Any::Moose;
  2         3  
  2         11  
10 2     2   2272 use HTTP::Request;
  2         62836  
  2         72  
11 2     2   2180 use JSON;
  2         29577  
  2         11  
12 2     2   1850 use YAML;
  2         14916  
  2         117  
13 2     2   1364 use Net::RackSpace::CloudServers::Image;
  2         6  
  2         71  
14 2     2   12 use Carp;
  2         3  
  2         453  
15              
16             has 'cloudservers' =>
17             ( is => 'rw', isa => 'Net::RackSpace::CloudServers', required => 1 );
18             has 'id' => ( is => 'ro', isa => 'Int', required => 1, default => 0 );
19             has 'name' => ( is => 'ro', isa => 'Str', required => 1 );
20             has 'imageid' => ( is => 'ro', isa => 'Maybe[Int]', required => 1 );
21             has 'flavorid' => ( is => 'ro', isa => 'Maybe[Int]', required => 1 );
22             has 'hostid' =>
23             ( is => 'ro', isa => 'Maybe[Str]', required => 1, default => undef );
24             has 'status' =>
25             ( is => 'ro', isa => 'Maybe[Str]', required => 1, default => undef );
26             has 'adminpass' =>
27             ( is => 'ro', isa => 'Maybe[Str]', required => 1, default => undef );
28             has 'progress' =>
29             ( is => 'ro', isa => 'Maybe[Str]', required => 1, default => undef );
30             has 'public_address' => (
31             is => 'ro',
32             isa => 'Maybe[ArrayRef[Str]]',
33             required => 1,
34             default => undef
35             );
36             has 'private_address' => (
37             is => 'ro',
38             isa => 'Maybe[ArrayRef[Str]]',
39             required => 1,
40             default => undef
41             );
42             has 'metadata' =>
43             ( is => 'ro', isa => 'Maybe[HashRef]', required => 1, default => undef );
44             has 'personality' =>
45             ( is => 'ro', isa => 'Maybe[ArrayRef]', required => 1, default => undef );
46              
47 2     2   34 no Any::Moose;
  2         4  
  2         14  
48             __PACKAGE__->meta->make_immutable();
49              
50             sub change_root_password {
51 0     0 1   my $self = shift;
52 0           my $password = shift;
53 0           my $uri = '/servers/' . $self->id;
54 0           my $request = HTTP::Request->new(
55             'PUT',
56             $self->cloudservers->server_management_url . $uri,
57             [
58             'X-Auth-Token' => $self->cloudservers->token,
59             'Content-Type' => 'application/json',
60             ],
61             to_json( { server => { adminPass => $password, } } )
62             );
63 0           my $response = $self->cloudservers->_request($request);
64 0 0         confess 'Unknown error' if $response->code != 202;
65 0           return $response;
66             }
67              
68             sub change_name {
69 0     0 1   my $self = shift;
70 0           my $name = shift;
71 0           my $uri = '/servers/' . $self->id;
72 0           my $request = HTTP::Request->new(
73             'PUT',
74             $self->cloudservers->server_management_url . $uri,
75             [
76             'X-Auth-Token' => $self->cloudservers->token,
77             'Content-Type' => 'application/json',
78             ],
79             to_json( { server => { name => $name, } } )
80             );
81 0           my $response = $self->cloudservers->_request($request);
82 0 0         confess 'Unknown error' if $response->code != 202;
83 0           return $response;
84             }
85              
86             sub delete_server {
87 0     0 1   my $self = shift;
88 0           my $request = HTTP::Request->new(
89             'DELETE',
90             $self->cloudservers->server_management_url . '/servers/' . $self->id,
91             [
92             'X-Auth-Token' => $self->cloudservers->token,
93             'Content-Type' => 'application/json',
94             ],
95             );
96 0           my $response = $self->cloudservers->_request($request);
97 0 0         confess 'Unknown error' if $response->code != 202;
98 0           return;
99             }
100              
101             sub create_image {
102 0     0 1   my $self = shift;
103 0           my $imgname = shift;
104 0           my $request = HTTP::Request->new(
105             'POST',
106             $self->cloudservers->server_management_url . '/images',
107             [
108             'X-Auth-Token' => $self->cloudservers->token,
109             'Content-Type' => 'application/json',
110             ],
111             to_json(
112             {
113             image => {
114             serverId => $self->id,
115             name => $imgname,
116             }
117             }
118             )
119             );
120 0           my $response = $self->cloudservers->_request($request);
121 0 0         if ( $response->code != 202 ) {
122 0           confess 'Unknown error ' . $response->code, "\n",
123             Dump( $response->content );
124             }
125 0           my $hash_response = from_json( $response->content );
126 0 0         if ( !defined $hash_response->{image} ) {
127 0           confess 'response does not contain "image":', Dump($hash_response);
128             }
129 0           return Net::RackSpace::CloudServers::Image->new(
130             cloudservers => $self->cloudservers,
131             id => $hash_response->{image}->{id},
132             serverid => $hash_response->{image}->{serverId},
133             name => $hash_response->{image}->{name},
134             created => $hash_response->{image}->{created},
135             status => $hash_response->{image}->{status},
136             progress => $hash_response->{image}->{status},
137             updated => undef,
138             );
139             }
140              
141             sub create_server {
142 0     0 1   my $self = shift;
143 0 0         my $request = HTTP::Request->new(
    0          
144             'POST',
145             $self->cloudservers->server_management_url . '/servers',
146             [
147             'X-Auth-Token' => $self->cloudservers->token,
148             'Content-Type' => 'application/json',
149             ],
150             to_json(
151             {
152             server => {
153             name => $self->name,
154             imageId => int $self->imageid,
155             flavorId => int $self->flavorid,
156             defined $self->metadata ? ( metadata => $self->metadata )
157             : (),
158             defined $self->personality
159             ? ( personality => $self->personality )
160             : (),
161             }
162             }
163             )
164             );
165 0           my $response = $self->cloudservers->_request($request);
166 0 0         confess 'Unknown error' if $response->code != 202;
167 0           my $hash_response = from_json( $response->content );
168 0 0         warn Dump($hash_response) if $DEBUG;
169 0 0         confess 'response does not contain key "server"'
170             if ( !defined $hash_response->{server} );
171 0 0         confess 'response does not contain hashref of "server"'
172             if ( ref $hash_response->{server} ne 'HASH' );
173 0           my $hserver = $hash_response->{server};
174 0           return __PACKAGE__->new(
175             cloudservers => $self->cloudservers,
176             adminpass => $hserver->{adminPass},
177             id => $hserver->{id},
178             name => $hserver->{name},
179             imageid => $hserver->{imageId},
180             flavorid => $hserver->{flavorId},
181             hostid => $hserver->{hostId},
182             status => $hserver->{status},
183             progress => $hserver->{progress},
184             public_address => $hserver->{addresses}->{public},
185             private_address => $hserver->{addresses}->{private},
186             metadata => $hserver->{metadata},
187             personality => $hserver->{personality},
188             );
189             }
190              
191             =head1 NAME
192              
193             Net::RackSpace::CloudServers::Server - a RackSpace CloudServers Server instance
194              
195             =head1 VERSION
196              
197             version 0.14
198              
199             =head1 SYNOPSIS
200              
201             use Net::RackSpace::CloudServers;
202             use Net::RackSpace::CloudServers::Server;
203             my $cs = Net::RackSpace::CloudServers->new( user => 'myusername', key => 'mysecretkey' );
204             my $server = Net::RackSpace::CloudServers::Server->new(
205             cloudservers => $cs,
206             id => '1', name => 'test',
207             );
208             # get list:
209             my @servers = $cs->get_server;
210             foreach my $server ( @servers ) {
211             print 'Have server ', $server->name, ' id ', $server->id, "\n";
212             }
213             # get detailed list
214             my @servers = $cs->get_server_detail();
215             foreach my $server ( @servers) {
216             print 'Have server ', $server->name, ' id ', $server->id,
217             # ...
218             "\n";
219             }
220              
221             ## Create server from template
222             my $tmp = Net::Rackspace::CloudServer::Server->new(
223             cloudservers => $cs, name => 'myserver',
224             flavor => 2, image => 8,
225             # others
226             );
227             my $srv = $tmp->create_server;
228             print "root pass: ", $srv->adminpass, " IP: @{$srv->public_address}\n";
229              
230             =head1 METHODS
231              
232             =head2 new / BUILD
233              
234             The constructor creates a Server object, see L<create_server> to create a server instance from a template:
235              
236             my $server = Net::RackSpace::CloudServers::Server->new(
237             cloudserver => $cs
238             id => 'id', name => 'name',
239             );
240              
241             This normally gets created for you by L<Net::RackSpace::Cloudserver>'s L<get_server> or L<get_server_detail> methods.
242             Needs a Net::RackSpace::CloudServers object as B<cloudservers> parameter.
243              
244             =head2 create_server
245              
246             This creates a real server based on a Server template object (TODO: will accept all the other build parameters).
247              
248             =head2 delete_server
249              
250             This will ask RackSpace to delete the cloud server instance specified in this object's ID from the system.
251             This operation is irreversible. Please notice that all images created from this server (if any) will also
252             be removed. This method doesn't return anything on success, and C<confess()>es on failure.
253              
254             =head2 change_name
255              
256             Changes the server's name to the new value given. Dies on error, or returns the response
257              
258             $srv->change_name('newname');
259              
260             =head2 change_root_password
261              
262             Changes the server's root password to the new value given. Dies on error, or returns the response
263              
264             $srv->change_root_password('toor');
265              
266             =head2 create_image
267              
268             Creates a named backup image of the current server. Returns the newly created
269             C<Net::RackSpace::CloudServers::Image> object, which includes the new image's C<id>.
270              
271             $srv->create_image("test backup 001");
272              
273             =head1 ATTRIBUTES
274              
275             =head2 id
276              
277             The id is used for the creation of new cloudservers
278              
279             =head2 name
280              
281             The name which identifies the server
282              
283             =head2 adminpass
284              
285             When newly built ONLY, the automatically generated password for root
286              
287             =head2 imageid
288              
289             The ID of the L<Net::RackSpace::CloudServer::Image> from which the server has been created
290              
291             =head2 flavorid
292              
293             The ID of the L<Net::RackSpace::CloudServer::Flavor> the server is currently running as
294              
295             =head2 hostid
296              
297             An ID which univocally identifies a server on your account. May not be unique across accounts.
298              
299             =head2 status
300              
301             The status of the server: building, etc
302              
303             =head2 progress
304              
305             The progress of the current B<status> operation: 60%, etc.
306              
307             =head2 public_address
308              
309             Arrayref containing the list of public addresses the server is configured to use
310              
311             =head2 private_address
312              
313             Arrayref containing the list of private addresses the server is configured to use
314              
315             =head2 metadata
316              
317             Hashref containing any metadata that has been set for the server
318              
319             =head1 AUTHOR
320              
321             Marco Fontani, C<< <mfontani at cpan.org> >>
322              
323             =head1 BUGS
324              
325             Please report any bugs or feature requests to C<bug-net-rackspace-cloudservers at rt.cpan.org>, or through
326             the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Net-RackSpace-CloudServers>. I will be notified, and then you'll
327             automatically be notified of progress on your bug as I make changes.
328              
329             =head1 SUPPORT
330              
331             You can find documentation for this module with the perldoc command.
332              
333             perldoc Net::RackSpace::CloudServers::Server
334              
335             You can also look for information at:
336              
337             =over 4
338              
339             =item * RT: CPAN's request tracker
340              
341             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Net-RackSpace-CloudServers>
342              
343             =item * AnnoCPAN: Annotated CPAN documentation
344              
345             L<http://annocpan.org/dist/Net-RackSpace-CloudServers>
346              
347             =item * CPAN Ratings
348              
349             L<http://cpanratings.perl.org/d/Net-RackSpace-CloudServers>
350              
351             =item * Search CPAN
352              
353             L<http://search.cpan.org/dist/Net-RackSpace-CloudServers/>
354              
355             =back
356              
357             =head1 COPYRIGHT & LICENSE
358              
359             Copyright 2009 Marco Fontani, all rights reserved.
360              
361             This program is free software; you can redistribute it and/or modify it
362             under the same terms as Perl itself.
363              
364             =cut
365              
366             1; # End of Net::RackSpace::CloudServers::Server