| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Etcd; | 
| 2 |  |  |  |  |  |  | $Etcd::VERSION = '0.004'; | 
| 3 |  |  |  |  |  |  | # ABSTRACT: Client library for etcd | 
| 4 |  |  |  |  |  |  |  | 
| 5 | 4 |  |  | 4 |  | 70709 | use namespace::autoclean; | 
|  | 4 |  |  |  |  | 80319 |  | 
|  | 4 |  |  |  |  | 24 |  | 
| 6 |  |  |  |  |  |  |  | 
| 7 | 4 |  |  | 4 |  | 3500 | use HTTP::Tiny 0.014; | 
|  | 4 |  |  |  |  | 199282 |  | 
|  | 4 |  |  |  |  | 179 |  | 
| 8 | 4 |  |  | 4 |  | 2221 | use URI::Escape qw(uri_escape); | 
|  | 4 |  |  |  |  | 4784 |  | 
|  | 4 |  |  |  |  | 225 |  | 
| 9 | 4 |  |  | 4 |  | 20 | use Carp qw(croak); | 
|  | 4 |  |  |  |  | 7 |  | 
|  | 4 |  |  |  |  | 160 |  | 
| 10 |  |  |  |  |  |  |  | 
| 11 | 4 |  |  | 4 |  | 4221 | use Moo; | 
|  | 4 |  |  |  |  | 36827 |  | 
|  | 4 |  |  |  |  | 21 |  | 
| 12 | 4 |  |  | 4 |  | 7875 | use Type::Utils qw(class_type); | 
|  | 4 |  |  |  |  | 118176 |  | 
|  | 4 |  |  |  |  | 38 |  | 
| 13 | 4 |  |  | 4 |  | 4400 | use Types::Standard qw(Str Int Bool HashRef); | 
|  | 4 |  |  |  |  | 151210 |  | 
|  | 4 |  |  |  |  | 50 |  | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | has host => ( is => 'ro', isa => Str, default => '127.0.0.1' ); | 
| 16 |  |  |  |  |  |  | has port => ( is => 'ro', isa => Int, default => 4001 ); | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | has ssl => ( is => 'ro', isa => Bool, default => 0 ); | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  | has http => ( is => 'lazy', isa => class_type('HTTP::Tiny') ); | 
| 21 | 6 |  |  | 6 |  | 2051 | sub _build_http { HTTP::Tiny->new }; | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | has version_prefix => ( is => 'ro', isa => Str, default => '/v2' ); | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | has _url_base => ( is => 'lazy' ); | 
| 26 |  |  |  |  |  |  | sub _build__url_base { | 
| 27 | 6 |  |  | 6 |  | 1259 | my ($self) = @_; | 
| 28 | 6 | 50 |  |  |  | 98 | ($self->ssl ? 'https' : 'http') .'://'.$self->host.':'.$self->port; | 
| 29 |  |  |  |  |  |  | } | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | sub _prep_url { | 
| 32 | 6 |  |  | 6 |  | 831 | my ($self, $path, %args) = @_; | 
| 33 | 6 |  |  |  |  | 19 | my $trailing = $path =~ m{/$}; | 
| 34 | 6 |  |  |  |  | 73 | my $url = $self->_url_base.join('/', map { uri_escape($_) } split('/', $path)); | 
|  | 22 |  |  |  |  | 238 |  | 
| 35 | 6 | 50 |  |  |  | 71 | $url .= '/' if $trailing; | 
| 36 | 6 | 100 |  |  |  | 78 | $url .= '?'.$self->http->www_form_urlencode(\%args) if %args; | 
| 37 | 6 |  |  |  |  | 194 | $url; | 
| 38 |  |  |  |  |  |  | } | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  | sub api_exec { | 
| 41 | 6 |  |  | 6 | 0 | 129 | my ($self, $path, $method, %args) = @_; | 
| 42 | 6 |  |  |  |  | 71 | my $res = $self->http->request($method, $self->_prep_url($path, %args)); | 
| 43 | 6 | 100 | 66 |  |  | 93 | $res = $self->http->request($method, $res->{headers}->{location}) | 
| 44 |  |  |  |  |  |  | if $res && $res->{status} eq 307; | 
| 45 | 6 | 50 |  |  |  | 59 | return $res if $res->{success}; | 
| 46 | 0 | 0 |  |  |  | 0 | croak "$res->{status} $res->{reason}: $res->{content}" if $res->{status} >= 500; | 
| 47 | 0 |  |  |  |  | 0 | require Etcd::Error; | 
| 48 | 0 |  |  |  |  | 0 | die Etcd::Error->new_from_http($res); | 
| 49 |  |  |  |  |  |  | } | 
| 50 |  |  |  |  |  |  |  | 
| 51 |  |  |  |  |  |  | sub server_version { | 
| 52 | 1 |  |  | 1 | 1 | 4249 | my ($self) = @_; | 
| 53 | 1 |  |  |  |  | 4 | my $res = $self->api_exec('/version', 'GET'); | 
| 54 | 1 |  |  |  |  | 6 | $res->{content}; | 
| 55 |  |  |  |  |  |  | } | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | with 'Etcd::Keys'; | 
| 58 |  |  |  |  |  |  | with 'Etcd::Stats'; | 
| 59 |  |  |  |  |  |  |  | 
| 60 |  |  |  |  |  |  | 1; | 
| 61 |  |  |  |  |  |  |  | 
| 62 |  |  |  |  |  |  | __END__ |