File Coverage

lib/Webservice/OVH/Cloud/Project/Instance.pm
Criterion Covered Total %
statement 15 246 6.1
branch 0 134 0.0
condition 0 18 0.0
subroutine 5 37 13.5
pod 28 28 100.0
total 48 463 10.3


line stmt bran cond sub pod time code
1             package Webservice::OVH::Cloud::Project::Instance;
2              
3             =encoding utf-8
4              
5             =head1 NAME
6              
7             Webservice::OVH::Cloud::Project::Instance
8              
9             =head1 SYNOPSIS
10              
11             use Webservice::OVH;
12            
13             my $ovh = Webservice::OVH->new_from_json("credentials.json");
14            
15             my $projects = $ovh->cloud->projects;
16             my $example_project = $projects->[0];
17            
18             my $instances = $project->instances;
19            
20             foreach my $instance (@$instances) {
21            
22             print @$instance->status;
23             $instance->delete;
24             }
25              
26             =head1 DESCRIPTION
27              
28             Access to instace functionality.
29              
30             =head1 METHODS
31              
32             =cut
33              
34 36     36   263 use strict;
  36         96  
  36         1274  
35 36     36   212 use warnings;
  36         102  
  36         1173  
36 36     36   216 use Carp qw{ carp croak };
  36         83  
  36         2168  
37 36     36   370 use JSON;
  36         81  
  36         343  
38              
39             our $VERSION = 0.46;
40              
41 36     36   23905 use Webservice::OVH::Cloud::Project::Instance::Group;
  36         134  
  36         118593  
42              
43             # Static Methods
44              
45             =head2 _new_empty
46              
47             Internal Method to create the Network object.
48             This method is not ment to be called directly.
49             This method is used when instance is initialised as a bridge object for static usage.
50              
51             =over
52              
53             =item * Parameter: %params - key => value
54              
55             =item * Return: L<Webservice::OVH::Cloud::Project::Instance>
56              
57             =item * Synopsis: Webservice::OVH::Cloud::Project::Instance->_new(wrapper => $ovh_api_wrapper, project => $project, module => $module );
58              
59             =back
60              
61             =cut
62              
63             sub _new_empty {
64              
65 0     0     my ( $class, %params ) = @_;
66            
67 0 0         die "Missing module" unless $params{module};
68 0 0         die "Missing wrapper" unless $params{wrapper};
69 0 0         die "Missing project" unless $params{project};
70              
71 0           my $module = $params{module};
72 0           my $api_wrapper = $params{wrapper};
73 0           my $project = $params{project};
74              
75 0           my $self = bless { _module => $module, _valid => 0, _api_wrapper => $api_wrapper, _project => $project, _available_groups => [], _groups => {} }, $class;
76             }
77              
78             =head2 group_exists
79              
80             Returns 1 if object is available, 0 if not.
81              
82             =over
83              
84             =item * Parameter: $group_id - api id, $no_recheck - (optional)only for internal usage
85              
86             =item * Return: VALUE
87              
88             =item * Synopsis: print "group exists" if $project->group_exists($id);
89              
90             =back
91              
92             =cut
93              
94             sub group_exists {
95              
96 0     0 1   my ( $self, $group_id, $no_recheck ) = @_;
97              
98 0 0         if ( !$no_recheck ) {
99              
100 0           my $api = $self->{_api_wrapper};
101 0           my $project_id = $self->project->id;
102 0           my $response = $api->rawCall( method => 'get', path => "/cloud/project/$project_id/instance/group", noSignature => 0 );
103 0 0         croak $response->error if $response->error;
104              
105 0           my $list = $response->content;
106              
107 0 0         return ( grep { $_ eq $group_id } @$list ) ? 1 : 0;
  0            
108              
109             } else {
110              
111 0           my $list = $self->{_available_groups};
112              
113 0 0         return ( grep { $_ eq $group_id } @$list ) ? 1 : 0;
  0            
114             }
115             }
116              
117             =head2 groups
118              
119             Produces an array of all available groups that are connected to the instance.
120              
121             =over
122              
123             =item * Return: ARRAY
124              
125             =item * Synopsis: my $instances = $instance->groups;
126              
127             =back
128              
129             =cut
130              
131             sub groups {
132              
133 0     0 1   my ($self) = @_;
134              
135 0           my $api = $self->{_api_wrapper};
136 0           my $project_id = $self->{_project}->id;
137 0           my $response = $api->rawCall( method => 'get', path => "/cloud/project/$project_id/instance/group", noSignature => 0 );
138 0 0         croak $response->error if $response->error;
139              
140 0           my $group_array = $response->content;
141 0           my $groups = [];
142 0           $self->{_available_groups} = $group_array;
143              
144 0           foreach my $group_id (@$group_array) {
145 0 0         if ( $self->group_exists( $group_id, 1 ) ) {
146 0   0       my $group = $self->{_groups}{$group_id} = $self->{_groups}{$group_id} || Webservice::OVH::Cloud::Project::Instance::Group->_new_existing( wrapper => $api, module => $self->{_module}, project => $self->project, id => $group_id );
147 0           push @$groups, $group;
148             }
149             }
150              
151 0           return $groups;
152             }
153              
154             =head2 group
155              
156             Returns a single group by id
157              
158             =over
159              
160             =item * Parameter: $group_id - api id
161              
162             =item * Return: L<Webservice::OVH::Cloud::Project::Instance::Group>
163              
164             =item * Synopsis: my $instance = $isntance->group($id);
165              
166             =back
167              
168             =cut
169              
170             sub group {
171              
172 0     0 1   my ( $self, $group_id ) = @_;
173              
174 0 0         if ( $self->group_exists($group_id) ) {
175              
176 0           my $api = $self->{_api_wrapper};
177 0   0       my $instance = $self->{_group}{$group_id} = $self->{_group}{$group_id} || Webservice::OVH::Cloud::Project::Instance->_new_existing( wrapper => $api, module => $self->{_module}, project => $self->project, id => $group_id );
178              
179 0           return $instance;
180             } else {
181              
182 0           carp "Instance $group_id doesn't exists";
183 0           return undef;
184             }
185             }
186              
187             =head2 create_group
188              
189             Creates a new group
190              
191             =over
192              
193             =item * Parameter: %params - key => value (required) region
194              
195             =item * Return: <Webservice::OVH::Cloud::Project::Instance::Group>
196              
197             =item * Synopsis: my $group = $project->create_instance( region => 'GRA1' );
198              
199             =back
200              
201             =cut
202              
203             sub create_group {
204              
205 0     0 1   my ( $self, %params ) = @_;
206              
207 0           my $api = $self->{_api_wrapper};
208 0           my $group = Webservice::OVH::Cloud::Project::Instance::Group->_new( wrapper => $api, module => $self->{_module}, project => $self->project, %params );
209             }
210              
211             =head2 _new_existing
212              
213             Internal Method to create the Instance object.
214             This method is not ment to be called directly.
215              
216             =over
217              
218             =item * Parameter: %params - key => value
219              
220             =item * Return: L<Webservice::OVH::Cloud::Project::Instance>
221              
222             =item * Synopsis: Webservice::OVH::Cloud::Project::Instance->_new( wrapper => $ovh_api_wrapper, project => $project, module => $module, id => $id );
223              
224             =back
225              
226             =cut
227              
228             sub _new_existing {
229              
230 0     0     my ( $class, %params ) = @_;
231              
232 0 0         die "Missing id" unless $params{id};
233 0 0         die "Missing module" unless $params{module};
234 0 0         die "Missing wrapper" unless $params{wrapper};
235 0 0         die "Missing project" unless $params{project};
236              
237 0           my $instance_id = $params{id};
238 0           my $module = $params{module};
239 0           my $api_wrapper = $params{wrapper};
240 0           my $project = $params{project};
241 0           my $project_id = $project->id;
242              
243 0           my $response = $api_wrapper->rawCall( method => 'get', path => "/cloud/project/$project_id/instance/$instance_id", noSignature => 0 );
244 0 0         carp $response->error if $response->error;
245              
246 0 0         if ( !$response->error ) {
247              
248 0           my $porperties = $response->content;
249 0           my $self = bless { _module => $module, _valid => 1, _api_wrapper => $api_wrapper, _id => $instance_id, _properties => $porperties, _project => $project }, $class;
250              
251 0           return $self;
252             } else {
253              
254 0           return undef;
255             }
256             }
257              
258             =head2 _new
259              
260             Internal Method to create the Instance object.
261             This method is not ment to be called directly.
262              
263             =over
264              
265             =item * Parameter: %params - key => value
266              
267             =item * Return: L<Webservice::OVH::Cloud::Project::Instance>
268              
269             =item * Synopsis: Webservice::OVH::Cloud::Project::Instance->_new(wrapper => $ovh_api_wrapper, project => $project, module => $module );
270              
271             =back
272              
273             =cut
274              
275             sub _new {
276              
277 0     0     my ( $class, %params ) = @_;
278              
279 0 0         die "Missing module" unless $params{module};
280 0 0         die "Missing wrapper" unless $params{wrapper};
281 0 0         die "Missing project" unless $params{project};
282              
283 0           my @keys = qw{ flavor_id image_id name region };
284 0 0         if ( my @missing_parameters = grep { not $params{$_} } @keys ) {
  0            
285              
286 0           croak "Missing parameter: @missing_parameters";
287             }
288              
289 0           my $module = $params{module};
290 0           my $api_wrapper = $params{wrapper};
291 0           my $project = $params{project};
292 0           my $project_id = $project->id;
293              
294 0 0 0       my $monthly_billing = $params{monthly_billing} && ( $params{monthly_billing} eq 'true' || $params{monthly_billing} eq 'yes' || $params{monthly_billing} eq '1' ) ? JSON::true : JSON::false;
295              
296 0           my $body = {};
297 0           $body->{flavorId} = $params{flavor_id};
298 0           $body->{imageId} = $params{image_id};
299 0           $body->{name} = $params{name};
300 0           $body->{region} = $params{region};
301 0 0         $body->{groupId} = $params{group_id} if exists $params{group_id};
302 0           $body->{monthlyBilling} = $monthly_billing;
303 0 0         $body->{sshKeyId} = $params{ssh_key_id} if exists $params{ssh_key_id};
304 0 0         $body->{userData} = $params{user_data} if exists $params{user_data};
305              
306 0           my $networks = $params{networks};
307              
308 0           foreach my $network (@$networks) {
309              
310 0           push @{ $body->{networks} }, { ip => $network->{ip}, networkId => $network->{network_id} };
  0            
311             }
312              
313 0           my $response = $api_wrapper->rawCall( method => 'post', path => "/cloud/project/$project_id/instance", body => $body, noSignature => 0 );
314 0 0         croak $response->error if $response->error;
315              
316 0           my $instance_id = $response->content->{id};
317 0           my $properties = $response->content;
318              
319 0           my $self = bless { _module => $module, _valid => 1, _api_wrapper => $api_wrapper, _id => $instance_id, _properties => $properties, _project => $project }, $class;
320              
321 0           return $self;
322             }
323              
324             =head2 id
325              
326             Returns the api id
327              
328             =over
329              
330             =item * Return: VALUE
331              
332             =item * Synopsis: my $id = $instance->id;
333              
334             =back
335              
336             =cut
337              
338             sub id {
339              
340 0     0 1   my ($self) = @_;
341              
342 0 0         return unless $self->_is_valid;
343              
344 0           return $self->{_id};
345             }
346              
347             =head2 is_valid
348              
349             When this object is deleted on the api side, this method returns 0.
350              
351             =over
352              
353             =item * Return: VALUE
354              
355             =item * Synopsis: print "Valid" if $instance->is_valid;
356              
357             =back
358              
359             =cut
360              
361             sub is_valid {
362              
363 0     0 1   my ($self) = @_;
364              
365 0           return $self->{_valid};
366             }
367              
368             =head2 _is_valid
369              
370             Internal method to check validity.
371             Difference is that this method carps an error.
372              
373             =over
374              
375             =item * Return: VALUE
376              
377             =item * Synopsis: $instance->_is_valid;
378              
379             =back
380              
381             =cut
382              
383             sub _is_valid {
384              
385 0     0     my ($self) = @_;
386              
387 0 0         carp "Instance is not valid anymore" unless $self->is_valid;
388 0           return $self->is_valid;
389             }
390              
391             =head2 project
392              
393             Root Project.
394              
395             =over
396              
397             =item * Return: L<Webservice::OVH::Cloud::Project>
398              
399             =item * Synopsis: my $project = $instance->project;
400              
401             =back
402              
403             =cut
404              
405             sub project {
406              
407 0     0 1   my ($self) = @_;
408              
409 0           return $self->{_project};
410             }
411              
412             =head2 properties
413              
414             Returns the raw properties as a hash.
415             This is the original return value of the web-api.
416              
417             =over
418              
419             =item * Return: HASH
420              
421             =item * Synopsis: my $properties = $instance->properties;
422              
423             =back
424              
425             =cut
426              
427             sub properties {
428              
429 0     0 1   my ($self) = @_;
430              
431 0 0         return unless $self->_is_valid;
432              
433 0           my $api = $self->{_api_wrapper};
434 0           my $id = $self->id;
435 0           my $project_id = $self->project->id;
436 0           my $response = $api->rawCall( method => 'get', path => "/cloud/project/$project_id/instance/group/$id", noSignature => 0 );
437 0 0         croak $response->error if $response->error;
438 0           $self->{_properties} = $response->content;
439 0           return $self->{_properties};
440             }
441              
442             =head2 description
443              
444             Exposed property value.
445              
446             =over
447              
448             =item * Return: VALUE
449              
450             =item * Synopsis: my $description = $instance->description;
451              
452             =back
453              
454             =cut
455              
456             sub description {
457              
458 0     0 1   my ($self) = @_;
459              
460 0 0         return unless $self->_is_valid;
461              
462 0           return $self->{description};
463             }
464              
465             =head2 status
466              
467             Exposed property value.
468              
469             =over
470              
471             =item * Return: VALUE
472              
473             =item * Synopsis: my $status = $instance->status;
474              
475             =back
476              
477             =cut
478              
479             sub status {
480              
481 0     0 1   my ($self) = @_;
482              
483 0 0         return unless $self->_is_valid;
484              
485 0           return $self->{_properties}->{status};
486             }
487              
488             =head2 name
489              
490             Exposed property value.
491              
492             =over
493              
494             =item * Return: VALUE
495              
496             =item * Synopsis: my $name = $instance->name;
497              
498             =back
499              
500             =cut
501              
502             sub name {
503              
504 0     0 1   my ($self) = @_;
505              
506 0 0         return unless $self->_is_valid;
507              
508 0           return $self->{_properties}->{name};
509             }
510              
511             =head2 region
512              
513             Exposed property value.
514              
515             =over
516              
517             =item * Return: VALUE
518              
519             =item * Synopsis: my $region = $instance->region;
520              
521             =back
522              
523             =cut
524              
525             sub region {
526              
527 0     0 1   my ($self) = @_;
528              
529 0 0         return unless $self->_is_valid;
530              
531 0           return $self->{_properties}->{region};
532             }
533              
534             =head2 image
535              
536             Exposed property value.
537              
538             =over
539              
540             =item * Return: <Webservice::OVH::Cloud::Project::Image>
541              
542             =item * Synopsis: my $image = $instance->image;
543              
544             =back
545              
546             =cut
547              
548             sub image {
549              
550 0     0 1   my ($self) = @_;
551              
552 0 0         return unless $self->_is_valid;
553              
554 0           my $image_id = $self->{_properties}->{image}->{id};
555              
556 0           my $image = $self->project->images($image_id);
557              
558 0           return $image;
559             }
560              
561             =head2 created
562              
563             Exposed property value.
564              
565             =over
566              
567             =item * Return: DateTime
568              
569             =item * Synopsis: my $dt_created = $instance->created;
570              
571             =back
572              
573             =cut
574              
575             sub created {
576              
577 0     0 1   my ($self) = @_;
578              
579 0 0         return unless $self->_is_valid;
580              
581 0           my $str_datetime = $self->{_properties}->{created};
582 0           my $datetime = Webservice::OVH::Helper->parse_datetime($str_datetime);
583 0           return $datetime;
584             }
585              
586             =head2 ssh_key
587              
588             Exposed property value.
589              
590             =over
591              
592             =item * Return: <Webservice::OVH::Cloud::Project::SSH>
593              
594             =item * Synopsis: my $ssh_key = $instance->ssh_key;
595              
596             =back
597              
598             =cut
599              
600             sub ssh_key {
601              
602 0     0 1   my ($self) = @_;
603              
604 0 0         return unless $self->_is_valid;
605              
606 0           my $key_id = $self->{_properties}->{sshKey}->{id};
607              
608 0           my $key = $self->project->images($key_id);
609              
610 0           return $key;
611             }
612              
613             =head2 monthly_billing
614              
615             Exposed property value.
616              
617             =over
618              
619             =item * Return: HASH
620              
621             =item * Synopsis: my $monthly_billing = $instance->monthly_billing;
622              
623             =back
624              
625             =cut
626              
627             sub monthly_billing {
628              
629 0     0 1   my ($self) = @_;
630              
631 0 0         return unless $self->_is_valid;
632              
633 0           return $self->{_properties}->{monthlyBilling};
634             }
635              
636             =head2 ip_addresses
637              
638             Exposed property value.
639              
640             =over
641              
642             =item * Return: ARRAY
643              
644             =item * Synopsis: my $ip_addresses = $instance->ip_addresses;
645              
646             =back
647              
648             =cut
649              
650             sub ip_addresses {
651              
652 0     0 1   my ($self) = @_;
653              
654 0 0         return unless $self->_is_valid;
655              
656 0           return $self->{_properties}->{ipAddresses};
657             }
658              
659             =head2 flavor
660              
661             Exposed property value.
662              
663             =over
664              
665             =item * Return: HASH
666              
667             =item * Synopsis: my $flavor = $instance->flavor;
668              
669             =back
670              
671             =cut
672              
673             sub flavor {
674              
675 0     0 1   my ($self) = @_;
676              
677 0 0         return unless $self->_is_valid;
678              
679 0           return $self->{_properties}->{flavor};
680             }
681              
682             =head2 change
683              
684             Changes the instance.
685              
686             =over
687              
688             =item * Parameter: $instance_name - instance name
689              
690             =item * Synopsis: $instance->change('Test Instance');
691              
692             =back
693              
694             =cut
695              
696             sub change {
697              
698 0     0 1   my ( $self, $instance_name ) = @_;
699              
700 0 0         return unless $self->_is_valid;
701              
702 0 0         croak "Missing instance_name" unless $instance_name;
703              
704 0           my $api = $self->{_api_wrapper};
705 0           my $project_id = $self->project_id;
706 0           my $instance_id = $self->id;
707              
708 0           my $response = $api->rawCall( method => 'put', path => "/cloud/project/$project_id/instance/$instance_id", body => { instanceName => $instance_name }, noSignature => 0 );
709 0 0         croak $response->error if $response->error;
710             }
711              
712             =head2 delete
713              
714             Deletes the object api sided and sets it invalid.
715              
716             =over
717              
718             =item * Synopsis: $instance->delete;
719              
720             =back
721              
722             =cut
723              
724             sub delete {
725              
726 0     0 1   my ($self) = @_;
727              
728 0 0         return unless $self->_is_valid;
729              
730 0           my $api = $self->{_api_wrapper};
731 0           my $project_id = $self->project->id;
732 0           my $instance_id = $self->id;
733              
734 0           my $response = $api->rawCall( method => 'delete', path => "/cloud/project/$project_id/instance/$instance_id", noSignature => 0 );
735 0 0         croak $response->error if $response->error;
736              
737 0           $self->{_valid} = 0;
738             }
739              
740             =head2 delete
741              
742             Activates monthly billing for rinstance.
743              
744             =over
745              
746             =item * Synopsis: $instance->active_monthly_billing;
747              
748             =back
749              
750             =cut
751              
752             sub active_monthly_billing {
753              
754 0     0 1   my ($self) = @_;
755              
756 0 0         return unless $self->_is_valid;
757              
758 0           my $api = $self->{_api_wrapper};
759 0           my $project_id = $self->project_id;
760 0           my $instance_id = $self->id;
761              
762 0           my $response = $api->rawCall( method => 'post', path => "/cloud/project/$project_id/instance/$instance_id/activeMonthlyBilling", body => {}, noSignature => 0 );
763 0 0         croak $response->error if $response->error;
764             }
765              
766             =head2 delete
767              
768             Return many statistics about the virtual machine for a given period
769              
770             =over
771              
772             =item * Return: HASH
773              
774             =item * Synopsis: $instance->monitoring;
775              
776             =back
777              
778             =cut
779              
780             sub monitoring {
781              
782 0     0 1   my ( $self, $period, $type ) = @_;
783              
784 0 0         return unless $self->_is_valid;
785              
786 0           my $api = $self->{_api_wrapper};
787 0           my $project_id = $self->project_id;
788 0           my $instance_id = $self->id;
789              
790 0           my $filter = Webservice::OVH::Helper->construct_filter( period => $period, type => $type );
791              
792 0           my $response = $api->rawCall( method => 'get', path => sprintf( "/cloud/project/$project_id/instance/$instance_id/monitoring%s", $filter ), noSignature => 0 );
793 0 0         croak $response->error if $response->error;
794              
795 0           return $response->content;
796             }
797              
798             =head2 reboot
799              
800             Reboots the instance. Options are soft or hard.
801              
802             =over
803              
804             =item * Parameter: $type - soft hard
805              
806             =item * Synopsis: $instance->reboot;
807              
808             =back
809              
810             =cut
811              
812             sub reboot {
813              
814 0     0 1   my ( $self, $type ) = @_;
815              
816 0 0         return unless $self->_is_valid;
817              
818 0 0 0       croak "Missing or wrong reboot type: hard, soft" unless $type && ( $type eq 'hard' || $type eq 'soft' );
      0        
819              
820 0           my $api = $self->{_api_wrapper};
821 0           my $project_id = $self->project_id;
822 0           my $instance_id = $self->id;
823              
824 0           my $response = $api->rawCall( method => 'post', path => "/cloud/project/$project_id/instance/$instance_id/reboot", body => { type => $type }, noSignature => 0 );
825 0 0         croak $response->error if $response->error;
826             }
827              
828             =head2 reinstall
829              
830             Reinstall an instance.
831              
832             =over
833              
834             =item * Parameter: $image_id - image id
835              
836             =item * Synopsis: $instance->reboot;
837              
838             =back
839              
840             =cut
841              
842             sub reinstall {
843              
844 0     0 1   my ( $self, $image_id ) = @_;
845              
846 0 0         return unless $self->_is_valid;
847              
848 0 0         croak "Missing image_id" unless $image_id;
849              
850 0           my $api = $self->{_api_wrapper};
851 0           my $project_id = $self->project_id;
852 0           my $instance_id = $self->id;
853              
854 0           my $response = $api->rawCall( method => 'post', path => "/cloud/project/$project_id/instance/$instance_id/reinstall", body => { imageId => $image_id }, noSignature => 0 );
855 0 0         croak $response->error if $response->error;
856             }
857              
858             =head2 rescue_mode
859              
860             Enable or disable rescue mode.
861              
862             =over
863              
864             =item * Parameter: $rescue - enabled or not (true/1), (optional) $image_id - image id
865              
866             =item * Synopsis: $instance->reboot;
867              
868             =back
869              
870             =cut
871              
872             sub rescue_mode {
873              
874 0     0 1   my ( $self, $rescue, $image_id ) = @_;
875              
876 0 0         return unless $self->_is_valid;
877              
878 0 0         croak "Missing image" unless $rescue;
879              
880 0 0 0       my $rescue_mode = $rescue && ( $rescue eq 'true' || $rescue eq '1' || $rescue eq 'yes' ) ? JSON::true : JSON::false;
881              
882 0           my $api = $self->{_api_wrapper};
883 0           my $project_id = $self->project_id;
884 0           my $instance_id = $self->id;
885 0           my $body = {};
886 0 0         $body->{imageId} = $image_id if $image_id;
887 0           $body->{rescue} = $rescue_mode;
888              
889 0           my $response = $api->rawCall( method => 'post', path => "/cloud/project/$project_id/instance/$instance_id/reinstall", body => $body, noSignature => 0 );
890 0 0         croak $response->error if $response->error;
891             }
892              
893             =head2 resize
894              
895             Migrate your instance to another flavor.
896              
897             =over
898              
899             =item * Parameter: $rescue - enabled or not (true/1), (optional) $image_id - image id
900              
901             =item * Synopsis: $instance->resize($flavor_id);
902              
903             =back
904              
905             =cut
906              
907             sub resize {
908              
909 0     0 1   my ( $self, $flavor_id ) = @_;
910              
911 0 0         return unless $self->_is_valid;
912              
913 0 0         croak "Missing flavor_id" unless $flavor_id;
914              
915 0           my $api = $self->{_api_wrapper};
916 0           my $project_id = $self->project_id;
917 0           my $instance_id = $self->id;
918              
919 0           my $response = $api->rawCall( method => 'post', path => "/cloud/project/$project_id/instance/$instance_id/resize", body => { flavorId => $flavor_id }, noSignature => 0 );
920 0 0         croak $response->error if $response->error;
921             }
922              
923             =head2 snapshot
924              
925             Snapshot an instance.
926              
927             =over
928              
929             =item * Parameter: $snapshotName - Name of the snapshot
930              
931             =item * Synopsis: $instance->snapshotName("Snapshot1");
932              
933             =back
934              
935             =cut
936              
937             sub snapshot {
938              
939 0     0 1   my ( $self, $snapshot_name ) = @_;
940              
941 0 0         return unless $self->_is_valid;
942              
943 0 0         croak "Missing snapshot_name" unless $snapshot_name;
944              
945 0           my $api = $self->{_api_wrapper};
946 0           my $project_id = $self->project_id;
947 0           my $instance_id = $self->id;
948              
949 0           my $response = $api->rawCall( method => 'post', path => "/cloud/project/$project_id/instance/$instance_id/snapshot", body => { snapshotName => $snapshot_name }, noSignature => 0 );
950 0 0         croak $response->error if $response->error;
951             }
952              
953             =head2 vnc
954              
955             Get VNC access to your instance.
956              
957             =over
958              
959             =item * Synopsis: $instance->vnc;
960              
961             =back
962              
963             =cut
964              
965             sub vnc {
966              
967 0     0 1   my ($self) = @_;
968              
969 0 0         return unless $self->_is_valid;
970              
971 0           my $api = $self->{_api_wrapper};
972 0           my $project_id = $self->project_id;
973 0           my $instance_id = $self->id;
974              
975 0           my $response = $api->rawCall( method => 'post', path => "/cloud/project/$project_id/instance/$instance_id/vnc", body => {}, noSignature => 0 );
976 0 0         croak $response->error if $response->error;
977              
978 0           return $response->content;
979             }
980              
981             1;