File Coverage

blib/lib/Net/Etcd.pm
Criterion Covered Total %
statement 48 82 58.5
branch 0 42 0.0
condition 0 3 0.0
subroutine 16 28 57.1
pod 11 11 100.0
total 75 166 45.1


line stmt bran cond sub pod time code
1 9     9   88104 use utf8;
  9         157  
  9         44  
2              
3             package Net::Etcd;
4              
5             # ABSTRACT: Provide access to the etcd v3 API.
6              
7 9     9   348 use strict;
  9         16  
  9         186  
8 9     9   43 use warnings;
  9         13  
  9         225  
9              
10 9     9   4749 use JSON;
  9         108098  
  9         69  
11 9     9   5323 use MIME::Base64;
  9         5279  
  9         719  
12 9     9   4449 use Types::Standard qw(Str Int Bool HashRef);
  9         710506  
  9         126  
13              
14 9     9   15424 use Net::Etcd::Auth;
  9         42  
  9         395  
15 9     9   4710 use Net::Etcd::Auth::RolePermission;
  9         41  
  9         332  
16 9     9   4364 use Net::Etcd::Config;
  9         32  
  9         309  
17 9     9   3837 use Net::Etcd::Watch;
  9         36  
  9         339  
18 9     9   4257 use Net::Etcd::Lease;
  9         33  
  9         313  
19 9     9   3956 use Net::Etcd::Maintenance;
  9         34  
  9         295  
20 9     9   3763 use Net::Etcd::Member;
  9         31  
  9         279  
21 9     9   3630 use Net::Etcd::User;
  9         37  
  9         322  
22              
23 9     9   69 use Moo;
  9         21  
  9         50  
24             with('Net::Etcd::KV');
25 9     9   3731 use namespace::clean;
  9         24  
  9         47  
26              
27             =encoding utf8
28              
29             =head1 NAME
30              
31             Net::Etcd - etcd v3 REST API.
32              
33             =cut
34              
35             our $VERSION = '0.021';
36              
37             =head1 SYNOPSIS
38              
39             Etcd v3.1.0 or greater is required. To use the v3 API make sure to set environment
40             variable ETCDCTL_API=3. Precompiled binaries can be downloaded at https://github.com/coreos/etcd/releases.
41              
42             $etcd = Net::Etcd->new(); # host: 127.0.0.1 port: 2379
43             $etcd = Net::Etcd->new({ host => $host, port => $port, ssl => 1 });
44              
45             # put key
46             $put_key = $etcd->put({ key =>'foo1', value => 'bar' });
47              
48             # check for success of a transaction
49             $put_key->is_success;
50              
51             # get single key
52             $key = $etcd->range({ key =>'test0' });
53              
54             # return single key value or the first in a list.
55             $key->get_value
56              
57             # get range of keys
58             $range = $etcd->range({ key =>'test0', range_end => 'test100' });
59              
60             # return array { key => value } pairs from range request.
61             my @users = $range->all
62              
63             # delete single key
64             $etcd->deleterange({ key => 'test0' });
65              
66             # watch key range, streaming.
67             $watch = $etcd->watch( { key => 'foo', range_end => 'fop'}, sub {
68             my ($result) = @_;
69             print STDERR Dumper($result);
70             })->create;
71              
72             # create/grant 20 second lease
73             $etcd->lease( { ID => 7587821338341002662, TTL => 20 } )->grant;
74              
75             # attach lease to put
76             $etcd->put( { key => 'foo2', value => 'bar2', lease => 7587821338341002662 } );
77              
78             # add new user
79             $etcd->user( { name => 'samba', password => 'foo' } )->add;
80              
81             # add new user role
82             $role = $etcd->role( { name => 'myrole' } )->add;
83              
84             # grant read permission for the foo key to myrole
85             $etcd->role_perm( { name => 'myrole', key => 'foo', permType => 'READWRITE' } )->grant;
86              
87             # grant role
88             $etcd->user_role( { user => 'samba', role => 'myrole' } )->grant;
89              
90             # defrag member's backend database
91             $defrag = $etcd->maintenance()->defragment;
92             print "Defrag request complete!" if $defrag->is_success;
93              
94             # member version
95             $v = $etcd->version;
96              
97             # list members
98             $etcd->member()->list;
99              
100             =head1 DESCRIPTION
101              
102             L is object oriented interface to the v3 REST API provided by the etcd L.
103              
104             =head1 ACCESSORS
105              
106             =head2 host
107              
108             The etcd host. Defaults to 127.0.0.1
109              
110             =cut
111              
112             has host => (
113             is => 'ro',
114             isa => Str,
115             default => '127.0.0.1'
116             );
117              
118             =head2 port
119              
120             Default 2379.
121              
122             =cut
123              
124             has port => (
125             is => 'ro',
126             isa => Int,
127             default => '2379'
128             );
129              
130             =head2 name
131              
132             Username for authentication, defaults to $ENV{ETCD_CLIENT_USERNAME}
133              
134             =cut
135              
136             has name => (
137             is => 'ro',
138             default => $ENV{ETCD_CLIENT_USERNAME}
139             );
140              
141             =head2 password
142              
143             Authentication credentials, defaults to $ENV{ETCD_CLIENT_PASSWORD}
144              
145             =cut
146              
147             has password => (
148             is => 'ro',
149             default => $ENV{ETCD_CLIENT_PASSWORD}
150             );
151              
152             =head2 ca_file
153              
154             Path to ca_file, defaults to $ENV{ETCD_CLIENT_CA_FILE}
155              
156             =cut
157              
158             has ca_file => (
159             is => 'ro',
160             default => $ENV{ETCD_CLIENT_CA_FILE}
161             );
162              
163             =head2 key_file
164              
165             Path to key_file, defaults to $ENV{ETCD_CLIENT_KEY_FILE}
166              
167             =cut
168              
169             has key_file => (
170             is => 'ro',
171             default => $ENV{ETCD_CLIENT_KEY_FILE}
172             );
173              
174             =head2 cert_file
175              
176             Path to cert_file, defaults to $ENV{ETCD_CLIENT_CERT_FILE}
177              
178             =cut
179              
180             has cert_file => (
181             is => 'ro',
182             default => $ENV{ETCD_CLIENT_CERT_FILE}
183             );
184              
185             =head2 cacert
186              
187             Path to cacert, defaults to $ENV{ETCD_CLIENT_CACERT_FILE}.
188              
189             =cut
190              
191             has cacert => (
192             is => 'ro',
193             default => $ENV{ETCD_CLIENT_CACERT_FILE}
194             );
195              
196             =head2 ssl
197              
198             To enable set to 1
199              
200             =cut
201              
202             has ssl => (
203             is => 'ro',
204             isa => Bool,
205             );
206              
207             =head2 api_version
208              
209             defaults to /v3beta
210              
211             =cut
212              
213             has api_version => (
214             is => 'ro',
215             isa => Str,
216             default => '/v3beta'
217             );
218              
219             =head2 api_path
220              
221             The full api path. Defaults to http://127.0.0.1:2379/v3alpha
222              
223             =cut
224              
225             has api_path => ( is => 'lazy' );
226              
227             sub _build_api_path {
228 0     0     my ($self) = @_;
229             return ( $self->{ssl}
230             || $self->{ca_file}
231             || $self->{key_file}
232             || $self->{cafile}
233 0 0 0       || $self->{cert_file} ? 'https' : 'http' )
234             . '://'
235             . $self->host . ':'
236             . $self->port
237             . $self->api_version;
238             }
239              
240             =head2 auth_token
241              
242             The token that is passed during authentication. This is generated during the
243             authentication process and stored until no longer valid or username is changed.
244              
245             =cut
246              
247             has auth_token => (
248             is => 'rwp',
249             clearer => 1,
250             );
251              
252             =head1 PUBLIC METHODS
253              
254             =head2 version
255              
256             Returns the etcd member version
257              
258             $etcd->version()
259              
260             =cut
261              
262             sub version {
263 0     0 1   my ( $self, $options ) = @_;
264 0 0         my $cb = pop if ref $_[-1] eq 'CODE';
265 0 0         my $member = Net::Etcd::Maintenance->new(
266             etcd => $self,
267             cb => $cb,
268             ( $options ? %$options : () ),
269             );
270 0           return $member->version;
271             }
272              
273             =head2 watch
274              
275             See L
276              
277             $etcd->watch({ key =>'foo', range_end => 'fop' })
278              
279             =cut
280              
281             sub watch {
282 0     0 1   my ( $self, $options ) = @_;
283 0 0         my $cb = pop if ref $_[-1] eq 'CODE';
284 0 0         return Net::Etcd::Watch->new(
285             etcd => $self,
286             cb => $cb,
287             ( $options ? %$options : () ),
288             );
289             }
290              
291             =head2 role
292              
293             See L
294              
295             $etcd->role({ role => 'foo' });
296              
297             =cut
298              
299             sub role {
300 0     0 1   my ( $self, $options ) = @_;
301 0 0         my $cb = pop if ref $_[-1] eq 'CODE';
302 0 0         return Net::Etcd::Auth::Role->new(
303             etcd => $self,
304             cb => $cb,
305             ( $options ? %$options : () ),
306             );
307             }
308              
309             =head2 role_perm
310              
311             See L
312              
313             Grants or revoke permission of a specified key or range to a specified role.
314              
315             $etcd->role_perm(
316             { name => 'myrole', key => 'bar', permType => 'READ', prefix => 1 } )->grant;
317              
318             =cut
319              
320             sub role_perm {
321 0     0 1   my ( $self, $options ) = @_;
322 0 0         my $cb = pop if ref $_[-1] eq 'CODE';
323 0 0         my $perm = Net::Etcd::Auth::RolePermission->new(
324             etcd => $self,
325             cb => $cb,
326             ( $options ? %$options : () ),
327             );
328             }
329              
330             =head2 user_role
331              
332             See L
333              
334             $etcd->user_role({ name => 'samba', role => 'foo' });
335              
336             =cut
337              
338             sub user_role {
339 0     0 1   my ( $self, $options ) = @_;
340 0 0         my $cb = pop if ref $_[-1] eq 'CODE';
341 0 0         return Net::Etcd::User::Role->new(
342             etcd => $self,
343             cb => $cb,
344             ( $options ? %$options : () ),
345             );
346             }
347              
348             =head2 auth
349              
350             See L
351              
352             $etcd->auth({ name => 'samba', password => 'foo' })->authenticate;
353             $etcd->auth()->enable;
354             $etcd->auth()->disable
355              
356             =cut
357              
358             sub auth {
359 0     0 1   my ( $self, $options ) = @_;
360 0 0         my $cb = pop if ref $_[-1] eq 'CODE';
361 0 0         return Net::Etcd::Auth->new(
362             etcd => $self,
363             cb => $cb,
364             ( $options ? %$options : () ),
365             );
366             }
367              
368             =head2 lease
369              
370             See L
371              
372             $etcd->lease( { ID => 7587821338341002662, TTL => 20 } )->grant;
373              
374             =cut
375              
376             sub lease {
377 0     0 1   my ( $self, $options ) = @_;
378 0 0         my $cb = pop if ref $_[-1] eq 'CODE';
379 0 0         return Net::Etcd::Lease->new(
380             etcd => $self,
381             cb => $cb,
382             ( $options ? %$options : () ),
383             );
384             }
385              
386             =head2 maintenance
387              
388             See L
389              
390             $etcd->maintenance()->snapshot
391              
392             =cut
393              
394             sub maintenance {
395 0     0 1   my ( $self, $options ) = @_;
396 0 0         my $cb = pop if ref $_[-1] eq 'CODE';
397 0 0         return Net::Etcd::Maintenance->new(
398             etcd => $self,
399             cb => $cb,
400             ( $options ? %$options : () ),
401             );
402             }
403              
404             =head2 member
405              
406             See L
407              
408             $etcd->member()->list
409              
410             =cut
411              
412             sub member {
413 0     0 1   my ( $self, $options ) = @_;
414 0 0         my $cb = pop if ref $_[-1] eq 'CODE';
415 0 0         return Net::Etcd::Member->new(
416             etcd => $self,
417             cb => $cb,
418             ( $options ? %$options : () ),
419             );
420             }
421              
422             =head2 user
423              
424             See L
425              
426             $etcd->user( { name => 'samba', password => 'foo' } )->add;
427              
428             =cut
429              
430             sub user {
431 0     0 1   my ( $self, $options ) = @_;
432 0 0         my $cb = pop if ref $_[-1] eq 'CODE';
433 0 0         return Net::Etcd::User->new(
434             etcd => $self,
435             cb => $cb,
436             ( $options ? %$options : () ),
437             );
438             }
439              
440             =head2 put
441              
442             See L
443              
444             $etcd->put({ key =>'foo1', value => 'bar' });
445              
446             =cut
447              
448             =head2 deleterange
449              
450             See L
451              
452             $etcd->deleterange({ key=>'test0' });
453              
454             =cut
455              
456             =head2 range
457              
458             See L
459              
460             $etcd->range({ key =>'test0', range_end => 'test100' });
461              
462             =cut
463              
464             =head2 txn
465              
466             See L
467              
468             $etcd->txn({ compare => \@compare, success => \@op });
469              
470             =cut
471              
472             =head2 op
473              
474             See L
475              
476             $etcd->op({ request_put => $put });
477             $etcd->op({ request_delete_range => $range });
478              
479             =cut
480              
481             =head2 compare
482              
483             See L
484              
485             $etcd->compare( { key => 'foo', result => 'EQUAL', target => 'VALUE', value => 'baz' });
486             $etcd->compare( { key => 'foo', target => 'CREATE', result => 'NOT_EQUAL', create_revision => '2' });
487              
488             =cut
489              
490             =head2 configuration
491              
492             Initialize configuration checks to see if etcd is installed locally.
493              
494             =cut
495              
496             sub configuration {
497 0     0 1   Net::Etcd::Config->configuration;
498             }
499              
500             =head1 AUTHOR
501              
502             Sam Batschelet (hexfusion)
503              
504             =head1 CONTRIBUTORS
505              
506             Ananth Kavuri
507              
508             =head1 ACKNOWLEDGEMENTS
509              
510             The L developers and community.
511              
512             =head1 CAVEATS
513              
514             The L v3 API is in heavy development and can change at anytime please see
515             L
516             for latest details.
517              
518             Authentication provided by this module will only work with etcd v3.3.0+
519              
520             =head1 LICENSE AND COPYRIGHT
521              
522             Copyright 2018 Sam Batschelet (hexfusion).
523              
524             This program is free software; you can redistribute it and/or modify it
525             under the terms of either: the GNU General Public License as published
526             by the Free Software Foundation; or the Artistic License.
527              
528             See http://dev.perl.org/licenses/ for more information.
529              
530             =cut
531              
532             1;