Skip to content

Commit

Permalink
Add token based authentication via grpc-gateway with tests. Fixes GH #18
Browse files Browse the repository at this point in the history
 (#22)
  • Loading branch information
hexfusion authored Jun 17, 2017
1 parent f83f146 commit 938ea5a
Show file tree
Hide file tree
Showing 12 changed files with 199 additions and 58 deletions.
7 changes: 4 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
sudo: required
env:
global:
- ETCD_VER=v3.2.0
- ETCD_VER=v3.2.0_plus_git
- ETCDCTL_API=3
- ETCD_TEST_HOST=127.0.0.1
- ETCD_TEST_PORT=2379
Expand All @@ -23,9 +23,10 @@ matrix:
env: COVERAGE=1 # enables coverage+coveralls reporting
before_install:
- curl https://coreos.com/dist/pubkeys/app-signing-pubkey.gpg | sudo apt-key add -
- wget https://github.com/coreos/etcd/releases/download/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -O /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
- wget https://github.com/hexfusion/etcd/releases/download/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -O /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
- mkdir -p /tmp/test-etcd
- tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/test-etcd --strip-components=1
- /tmp/test-etcd/etcd -version
- /tmp/test-etcd/etcd&
- sleep 3
- git clone git://github.com/travis-perl/helpers ~/travis-perl-helpers
Expand All @@ -40,4 +41,4 @@ install:
script:
- perl Makefile.PL
- make
- prove -b -r -s -j$(test-jobs) $(test-files)
- make test
107 changes: 67 additions & 40 deletions lib/Net/Etcd.pm
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ our $VERSION = '0.011';
# attach lease to put
$etcd->put( { key => 'foo2', value => 'bar2', lease => 7587821338341002662 } );
# add new user
$etcd->user( { name => 'samba', password => 'foo' } )->add;
# add new user role
$role = $etcd->role( { name => 'myrole' } )->add;
# grant role
$etcd->user_role( { user => 'samba', role => 'myrole' } )->grant;
=head1 DESCRIPTION
L<Net::Etcd> is object oriented interface to the v3 REST API provided by the etcd L<grpc-gateway|https://github.com/grpc-ecosystem/grpc-gateway>.
Expand All @@ -74,6 +83,8 @@ L<Net::Etcd> is object oriented interface to the v3 REST API provided by the etc
=head2 host
The etcd host. Defaults to 127.0.0.1
=cut

has host => (
Expand All @@ -84,6 +95,8 @@ has host => (

=head2 port
Default 2379.
=cut

has port => (
Expand All @@ -92,7 +105,9 @@ has port => (
default => '2379'
);

=head2 username
=head2 name
Username for authentication
=cut

Expand All @@ -103,6 +118,8 @@ has name => (

=head2 password
Authentication credentials
=cut

has password => (
Expand All @@ -112,69 +129,55 @@ has password => (

=head2 ssl
To enable set to 1
=cut

has ssl => (
is => 'ro',
isa => Bool,
);

=head2 api_root
=cut

has api_root => ( is => 'lazy' );

sub _build_api_root {
my ($self) = @_;
return
( $self->ssl ? 'https' : 'http' ) . '://'
. $self->host . ':'
. $self->port;
}

=head2 api_prefix
=head2 api_version
defaults to /v3alpha
=cut

has api_prefix => (
has api_version => (
is => 'ro',
isa => Str,
default => '/v3alpha'
);

=head2 api_path
The full api path. Defaults to http://127.0.0.1:2379/v3alpha
=cut

has api_path => ( is => 'lazy' );

sub _build_api_path {
my ($self) = @_;
return $self->api_root . $self->api_prefix;
return ( $self->ssl ? 'https' : 'http' ) . '://'
. $self->host . ':'. $self->port . $self->api_version;
}

=head2 auth_token
=cut
The token that is passed during authentication. This is generated during the
authentication process and stored until no longer valid or username is changed.
has auth_token => ( is => 'lazy' );
=cut

sub _build_auth_token {
my ($self) = @_;
return Net::Etcd::Auth::Authenticate->new(
etcd => $self,
%$self
)->token;
}
has auth_token => ( is => 'rwp' );

=head1 PUBLIC METHODS
=head2 watch
Returns a L<Net::Etcd::Watch> object.
See L<Net::Etcd::Watch>
$etcd->watch({ key =>'foo', range_end => 'fop' })
Expand All @@ -192,7 +195,7 @@ sub watch {

=head2 role
Returns a L<Net::Etcd::Auth::Role> object.
See L<Net::Etcd::Auth::Role>
$etcd->role({ role => 'foo' });
Expand All @@ -210,7 +213,7 @@ sub role {

=head2 user_role
Returns a L<Net::Etcd::User::Role> object.
See L<Net::Etcd::User::Role>
$etcd->user_role({ name => 'samba', role => 'foo' });
Expand All @@ -228,7 +231,11 @@ sub user_role {

=head2 auth
Returns a L<Net::Etcd::Auth> object.
See L<Net::Etcd::Auth>
$etcd->auth({ name => 'samba', password => 'foo' })->authenticate;
$etcd->auth()->enable;
$etcd->auth()->disable
=cut

Expand All @@ -244,7 +251,9 @@ sub auth {

=head2 lease
Returns a L<Net::Etcd::Lease> object.
See L<Net::Etcd::Lease>
$etcd->lease( { ID => 7587821338341002662, TTL => 20 } )->grant;
=cut

Expand All @@ -260,7 +269,9 @@ sub lease {

=head2 maintenance
Returns a L<Net::Etcd::Maintenance> object.
See L<Net::Etcd::Maintenance>
$etcd->maintenance()->snapshot
=cut

Expand All @@ -276,7 +287,9 @@ sub maintenance {

=head2 user
Returns a L<Net::Etcd::User> object.
See L<Net::Etcd::User>
$etcd->user( { name => 'samba', password => 'foo' } )->add;
=cut

Expand All @@ -292,31 +305,43 @@ sub user {

=head2 put
Returns a L<Net::Etcd::KV::Put> object.
See L<Net::Etcd::KV::Put>
$etcd->put({ key =>'foo1', value => 'bar' });
=cut

=head2 range
Returns a L<Net::Etcd::KV::Range> object.
See L<Net::Etcd::KV::Range>
$etcd->range({ key =>'test0', range_end => 'test100' });
=cut

=head2 txn
Returns a L<Net::Etcd::KV::Txn> object.
See L<Net::Etcd::KV::Txn>
$etcd->txn({ compare => \@compare, success => \@op });
=cut

=head2 op
Returns a L<Net::Etcd::KV::Op> object.
See L<Net::Etcd::KV::Op>
$etcd->op({ request_put => $put });
$etcd->op({ request_delete_range => $range });
=cut

=head2 compare
Returns a L<Net::Etcd::KV::Compare> object.
See L<Net::Etcd::KV::Compare>
$etcd->compare( { key => 'foo', result => 'EQUAL', target => 'VALUE', value => 'baz' });
$etcd->compare( { key => 'foo', target => 'CREATE', result => 'NOT_EQUAL', create_revision => '2' });
=cut

Expand All @@ -337,6 +362,8 @@ sub BUILD {
$msg .= ">> Please install etcd - https://coreos.com/etcd/docs/latest/";
die $msg;
}
# set the intial auth token
$self->auth()->authenticate;
}

=head1 AUTHOR
Expand All @@ -350,7 +377,7 @@ The L<etcd|https://github.com/coreos/etcd> developers and community.
=head1 CAVEATS
The L<etcd|https://github.com/coreos/etcd> v3 API is in heavy development and can change at anytime please see
https://github.com/coreos/etcd/blob/master/Documentation/dev-guide/api_reference_v3.md
L<api_reference_v3|https://github.com/coreos/etcd/blob/master/Documentation/dev-guide/api_reference_v3.md>
for latest details.
=head1 LICENSE AND COPYRIGHT
Expand Down
46 changes: 35 additions & 11 deletions lib/Net/Etcd/Auth.pm
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ use warnings;
=cut

use Moo;
use JSON;
use Carp;
use Types::Standard qw(Str Int Bool HashRef ArrayRef);
use Net::Etcd::Auth::Role;
use Data::Dumper;

with 'Net::Etcd::Role::Actions';

Expand Down Expand Up @@ -57,41 +59,60 @@ has endpoint => (
isa => Str,
);

=head2 password
=head2 name
Defaults to $etcd->name
=cut

has name => (
is => 'ro',
isa => Str,
is => 'lazy',
);

sub _build_name {
my ($self) = @_;
my $user = $self->etcd->name;
return $user if $user;
return;
}

=head2 password
Defaults to $etcd->password
=cut

has password => (
is => 'ro',
isa => Str,
is => 'lazy',
);

sub _build_password {
my ($self) = @_;
my $pwd = $self->etcd->password;
return $pwd if $pwd;
return;
}

=head1 PUBLIC METHODS
=head2 authenticate
Enable authentication, this requires name and password.
Returns token with valid authentication.
$etcd->auth({ name => $user, password => $pass })->authenticate;
my $token = $etcd->auth({ name => $user, password => $pass })->authenticate;
=cut

sub authenticate {
my ( $self, $options ) = @_;
$self->{endpoint} = '/auth/authenticate';
confess 'name and password required for ' . __PACKAGE__ . '->authenticate'
unless ($self->{password} && $self->{name});
return unless ($self->password && $self->name);
$self->request;
return $self;
my $auth = from_json($self->{response}{content});
if ($auth && defined $auth->{token}) {
$self->etcd->{auth_token} = $auth->{token};
}
return;
}

=head2 enable
Expand All @@ -107,6 +128,9 @@ sub enable {
$self->{endpoint} = '/auth/enable';
$self->{json_args} = '{}';
$self->request;

# init token
$self->etcd->auth()->authenticate;
return $self;
}

Expand All @@ -122,7 +146,7 @@ sub disable {
my ( $self, $options ) = @_;
$self->{endpoint} = '/auth/disable';
confess 'root name and password required for ' . __PACKAGE__ . '->disable'
unless ($self->{password} && $self->{name});
unless ($self->password && $self->name);
$self->request;
return $self;
}
Expand Down
Loading

0 comments on commit 938ea5a

Please sign in to comment.