File Coverage

blib/lib/WWW/VastAI/Role/OperationMap.pm
Criterion Covered Total %
statement 28 30 93.3
branch 16 20 80.0
condition 4 6 66.6
subroutine 6 6 100.0
pod 1 1 100.0
total 55 63 87.3


line stmt bran cond sub pod time code
1             package WWW::VastAI::Role::OperationMap;
2             our $VERSION = '0.001';
3             # ABSTRACT: Central Vast.ai API operation mapping used by WWW::VastAI
4              
5 10     10   5872 use Moo::Role;
  10         23  
  10         70  
6 10     10   4924 use Carp qw(croak);
  10         21  
  10         9677  
7              
8             requires 'base_url';
9             requires 'base_url_v1';
10             requires 'run_url';
11             requires 'get';
12             requires 'post';
13             requires 'put';
14             requires 'delete';
15              
16             has operation_map => (
17             is => 'lazy',
18             builder => '_build_operation_map',
19             );
20              
21             sub _build_operation_map {
22             return {
23 6     6   643 searchOffers => { method => 'POST', base => 'v0', path => '/bundles/' },
24             listInstances => { method => 'GET', base => 'v0', path => '/instances/' },
25             getInstance => { method => 'GET', base => 'v0', path => '/instances/{id}/' },
26             createInstance => { method => 'PUT', base => 'v0', path => '/asks/{id}/' },
27             manageInstance => { method => 'PUT', base => 'v0', path => '/instances/{id}/' },
28             deleteInstance => { method => 'DELETE', base => 'v0', path => '/instances/{id}/' },
29             requestInstanceLogs => { method => 'PUT', base => 'v0', path => '/instances/request_logs/{id}' },
30             listInstanceSSHKeys => { method => 'GET', base => 'v0', path => '/instances/{id}/ssh/' },
31             attachInstanceSSHKey => { method => 'POST', base => 'v0', path => '/instances/{id}/ssh/' },
32             detachInstanceSSHKey => { method => 'DELETE', base => 'v0', path => '/instances/{id}/ssh/{ssh_key_id}/' },
33             searchTemplates => { method => 'GET', base => 'v0', path => '/template/' },
34             createTemplate => { method => 'POST', base => 'v0', path => '/template/' },
35             updateTemplate => { method => 'PUT', base => 'v0', path => '/template/' },
36             deleteTemplate => { method => 'DELETE', base => 'v0', path => '/template/' },
37             listVolumes => { method => 'GET', base => 'v0', path => '/volumes/' },
38             createVolume => { method => 'PUT', base => 'v0', path => '/volumes/' },
39             deleteVolume => { method => 'DELETE', base => 'v0', path => '/volumes/' },
40             listSSHKeys => { method => 'GET', base => 'v0', path => '/ssh/' },
41             createSSHKey => { method => 'POST', base => 'v0', path => '/ssh/' },
42             updateSSHKey => { method => 'PUT', base => 'v0', path => '/ssh/{id}/' },
43             deleteSSHKey => { method => 'DELETE', base => 'v0', path => '/ssh/{id}/' },
44             listAPIKeys => { method => 'GET', base => 'v0', path => '/auth/apikeys/' },
45             createAPIKey => { method => 'POST', base => 'v0', path => '/auth/apikeys/' },
46             deleteAPIKey => { method => 'DELETE', base => 'v0', path => '/auth/apikeys/{id}/' },
47             getCurrentUser => { method => 'GET', base => 'v0', path => '/users/current/' },
48             listEnvVars => { method => 'GET', base => 'v0', path => '/secrets/' },
49             createEnvVar => { method => 'POST', base => 'v0', path => '/secrets/' },
50             updateEnvVar => { method => 'PUT', base => 'v0', path => '/secrets/' },
51             deleteEnvVar => { method => 'DELETE', base => 'v0', path => '/secrets/' },
52             listInvoices => { method => 'GET', base => 'v1', path => '/invoices/' },
53             listEndpoints => { method => 'GET', base => 'v0', path => '/endptjobs/' },
54             createEndpoint => { method => 'POST', base => 'v0', path => '/endptjobs/' },
55             deleteEndpoint => { method => 'DELETE', base => 'v0', path => '/endptjobs/{id}/' },
56             listWorkergroups => { method => 'GET', base => 'v0', path => '/workergroups/' },
57             createWorkergroup => { method => 'POST', base => 'v0', path => '/workergroups/' },
58             updateWorkergroup => { method => 'PUT', base => 'v0', path => '/workergroups/{id}/' },
59             deleteWorkergroup => { method => 'DELETE', base => 'v0', path => '/workergroups/{id}/' },
60             getEndpointLogs => { method => 'POST', base => 'run', path => '/get_endpoint_logs/' },
61             getEndpointWorkers => { method => 'POST', base => 'run', path => '/get_endpoint_workers/' },
62             getWorkergroupLogs => { method => 'POST', base => 'run', path => '/get_workergroup_logs/' },
63             getWorkergroupWorkers => { method => 'POST', base => 'run', path => '/get_workergroup_workers/' },
64             };
65             }
66              
67             sub _base_for_operation {
68 46     46   101 my ($self, $base) = @_;
69 46 100       1024 return $self->base_url if $base eq 'v0';
70 5 100       44 return $self->base_url_v1 if $base eq 'v1';
71 4 50       26 return $self->run_url if $base eq 'run';
72 0         0 croak "Unknown Vast.ai API base '$base'";
73             }
74              
75             sub _expand_path {
76 46     46   179 my ($self, $path, $vars) = @_;
77              
78 46   100     218 $vars ||= {};
79 46         184 $path =~ s/\{([^}]+)\}/
80             exists $vars->{$1}
81 20 50       152 ? $vars->{$1}
82             : croak "Missing path parameter '$1'"
83             /ge;
84              
85 46         172 return $path;
86             }
87              
88             sub request_op {
89 46     46 1 169 my ($self, $name, %args) = @_;
90              
91 46 50       1145 my $op = $self->operation_map->{$name}
92             or croak "Unknown Vast.ai operation '$name'";
93              
94 46         541 my $path = $self->_expand_path($op->{path}, $args{path});
95             my %http_opts = (
96 46         165 base_url => $self->_base_for_operation($op->{base}),
97             );
98              
99 46 100       405 if ($op->{method} eq 'GET') {
100 15 100       106 return $self->get($path, %http_opts, ($args{query} ? (params => $args{query}) : ()));
101             }
102 31 100       114 if ($op->{method} eq 'POST') {
103 12   50     92 return $self->post($path, ($args{body} || {}), %http_opts);
104             }
105 19 100       74 if ($op->{method} eq 'PUT') {
106 10   50     73 return $self->put($path, ($args{body} || {}), %http_opts);
107             }
108 9 50       39 if ($op->{method} eq 'DELETE') {
109 9         64 return $self->delete($path, $args{body}, %http_opts);
110             }
111              
112 0           croak "Unsupported HTTP method '$op->{method}'";
113             }
114              
115             1;
116              
117             __END__