EV-Etcd
view release on metacpan or search on metacpan
Makefile.PL view on Meta::CPAN
my $grpc_cflags = `pkg-config --cflags grpc 2>/dev/null` || '';
my $grpc_libs = `pkg-config --libs grpc 2>/dev/null` || '-lgrpc';
chomp($grpc_cflags, $grpc_libs);
# Try pkg-config for libprotobuf-c
my $protobuf_c_cflags = `pkg-config --cflags libprotobuf-c 2>/dev/null` || '';
my $protobuf_c_libs = `pkg-config --libs libprotobuf-c 2>/dev/null` || '-lprotobuf-c';
chomp($protobuf_c_cflags, $protobuf_c_libs);
# Detect gRPC API version for channel creation compatibility
# - gRPC >= ~1.42: grpc_insecure_credentials_create() + grpc_channel_create()
# - gRPC < ~1.42: grpc_insecure_channel_create()
# The new API header moved from grpc_security.h to credentials.h in ~1.65
use File::Temp qw(tempdir);
my $grpc_api_defines = '';
my $tmpdir = tempdir(CLEANUP => 1);
sub try_compile {
my ($cflags, $code) = @_;
open my $fh, '>', "$tmpdir/test.c" or return 0;
print $fh $code;
close $fh;
my $cc = $Config{cc} || 'cc';
Makefile.PL view on Meta::CPAN
Install them with:
Debian/Ubuntu: apt install libgrpc-dev libgrpc++-dev libprotobuf-c-dev
macOS: brew install grpc protobuf-c
FreeBSD: pkg install grpc protobuf-c
*******************************************
MSG
exit 0; # exit 0 = NA on CPAN Testers (not a test failure)
}
# Check for grpc/credentials.h (gRPC >= ~1.65)
if (try_compile($all_cflags, <<'END')) {
#include <grpc/credentials.h>
int main(void) { return 0; }
END
$grpc_api_defines .= ' -DHAVE_GRPC_CREDENTIALS_H';
print "Detected <grpc/credentials.h>\n";
}
# Check for new credentials-based channel API
my $creds_test_header = ($grpc_api_defines =~ /HAVE_GRPC_CREDENTIALS_H/)
? '#include <grpc/credentials.h>' : '#include <grpc/grpc_security.h>';
if (try_compile("$all_cflags $grpc_api_defines", <<"END")) {
#include <grpc/grpc.h>
$creds_test_header
void test(void) { grpc_channel_credentials *c = grpc_insecure_credentials_create(); (void)c; }
int main(void) { return 0; }
END
$grpc_api_defines .= ' -DHAVE_GRPC_NEW_CHANNEL_API';
print "Detected grpc_insecure_credentials_create (new channel API)\n";
} else {
print "Using legacy grpc_insecure_channel_create\n";
}
WriteMakefile(
NAME => 'EV::Etcd',
VERSION_FROM => 'lib/EV/Etcd.pm',
ABSTRACT_FROM => 'lib/EV/Etcd.pm',
AUTHOR => 'vividsnow',
LICENSE => 'perl_5',
etcd_common.h view on Meta::CPAN
/* Threading support for hybrid gRPC/EV approach */
#include <pthread.h>
/* Reconnect backoff: 0.5s * attempt (capped at 5s) */
#define RECONNECT_BACKOFF_SECONDS(attempt) \
((attempt) * 0.5 > 5.0 ? 5.0 : (attempt) * 0.5)
#include <grpc/grpc.h>
#ifdef HAVE_GRPC_CREDENTIALS_H
#include <grpc/credentials.h>
#else
#include <grpc/grpc_security.h>
#endif
#include <grpc/byte_buffer.h>
#include <grpc/byte_buffer_reader.h>
/*
* gRPC channel creation compatibility.
* - New API (>= ~1.42): grpc_insecure_credentials_create + grpc_channel_create
* - Old API (< ~1.42): grpc_insecure_channel_create
*/
static inline grpc_channel *
etcd_create_insecure_channel(const char *target, const grpc_channel_args *args) {
#ifdef HAVE_GRPC_NEW_CHANNEL_API
grpc_channel_credentials *creds = grpc_insecure_credentials_create();
grpc_channel *channel = grpc_channel_create(target, creds, args);
grpc_channel_credentials_release(creds);
return channel;
#else
return grpc_insecure_channel_create(target, args, NULL);
#endif
}
#include "kv.pb-c.h"
#include "rpc.pb-c.h"
#include "lock.pb-c.h"
#include "election.pb-c.h"
etcd_common.h view on Meta::CPAN
} \
} while (0)
#define VALIDATE_VALUE_SIZE(value_len) \
do { \
if ((value_len) > ETCD_MAX_VALUE_SIZE) { \
croak("value too large: %zu bytes (max %d)", (size_t)(value_len), ETCD_MAX_VALUE_SIZE); \
} \
} while (0)
/* Auth input limits - prevent DoS via oversized credentials */
#define ETCD_MAX_USERNAME_SIZE 256 /* Reasonable username limit */
#define ETCD_MAX_PASSWORD_SIZE 4096 /* Reasonable password limit */
#define VALIDATE_USERNAME_SIZE(len) \
do { \
if ((len) > ETCD_MAX_USERNAME_SIZE) { \
croak("username too large: %zu bytes (max %d)", (size_t)(len), ETCD_MAX_USERNAME_SIZE); \
} \
} while (0)
lib/EV/Etcd.pm view on Meta::CPAN
=back
B<Note>: You can also release a lock by revoking its associated lease with
C<lease_revoke>. This is useful if you want to release all resources
associated with a lease at once.
=head1 AUTHENTICATION SERVICE
EV::Etcd provides full support for etcd's authentication and authorization
system. Authentication uses username/password credentials, and authorization
is based on roles with key-range permissions.
=head2 authenticate
$client->authenticate($username, $password, $callback);
Authenticate with etcd using username and password. On success, the client
automatically stores the auth token and uses it for subsequent requests.
Arguments:
{
my $wrong_err;
$client->authenticate($test_user, 'wrong-password', sub {
my ($resp, $err) = @_;
$wrong_err = $err;
EV::break;
});
my $t_wrong = EV::timer(5, 0, sub { fail('timeout'); EV::break });
EV::run;
# Should return an error (either auth not enabled, or invalid credentials)
ok($wrong_err, 'authenticate with wrong password returns error');
diag("Wrong password error: " . ($wrong_err->{message} // $wrong_err));
}
# Test 21-22: user_change_password
{
my $change_result;
my $change_err;
$client->user_change_password($test_user, 'new-password-456', sub {
my ($resp, $err) = @_;
( run in 1.176 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )