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