Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
It is generated JSON file of serf dynamically by etcd. I made it experimentally, but do not maintain it recently.
#!/usr/bin/perl
# Serf configuration generator with Etcd
#
# MIT License
# 2014 Masahito Zembutsu
use JSON::XS;
use Net::HTTP;
use Data::Dumper;
my $target = '/serf/manager';
# etcd
my $etcd_host = '127.0.0.1';
my $etcd_port = '4001';
my $etcd_ver = 'v2';
# no buffering
$| = 1;
# define as objects
my $config_obj = 'event_handlers|start_join';
# debug
$ERR = 0;
# get JSON data
my $json_str = &etcd_request($target);
# checking format
#if (valid_json ($json_str)) {
# #print "valid json: $@\n";
#} else{
# #print "invalid json: $@\n";
#}
# decode JSON
$config = JSON::XS->new->utf8->decode($json_str);
my @nodes = @{$config->{'node'}->{'nodes'}};
$target = $config->{'node'}->{'key'};
$target .= '/' if ( $target !~ /(\/)$/ );
my %OUTPUT;
foreach my $key (@nodes) {
$key->{'key'} =~ s/$target//;
if ($key->{dir} == 1 ) {
my @data = @{$key->{'nodes'}};
if ($key->{'key'} =~ /$config_obj/) {
my @newdata;
} elsif ($key->{'key'} eq 'keys' ) {
my %newdata;
}
foreach my $tmp (@data) {
my $cut = $target.$key->{key}.'/';
$tmp->{key} =~ s/$cut//;
if ($key->{'key'} =~ /$config_obj/) {
push @newdata, $tmp->{'value'};
} elsif ($key->{'key'} eq 'keys' ) {
$newdata{$tmp->{'key'}} = $tmp->{'value'};
}
}
if ($key->{'key'} =~ /$config_obj/) {
$key->{'value'} = \@newdata;
} elsif ($key->{'key'} eq 'keys' ) {
$key->{'value'} = \%newdata;
}
}
$OUTPUT{$key->{'key'}} = $key->{'value'};
}
# Display output
my $NEWJSON = JSON::XS->new->utf8->encode( \%OUTPUT );
print $NEWJSON,"\n";
exit;
sub etcd_request {
my $request = shift;
%headers = ('Content-Type' => 'application/json-rpc');
my $nh = Net::HTTP->new(Host => $etcd_host, PeerPort => $etcd_port) or $ERR = 1;
my $req = '/'.$etcd_ver.'/keys'.$request.'?recursive=true&sorted=true';
$nh->write_request('GET', $req , %headers , '') or $ERR = 2;
my ($code, $mess, %headers) = $nh->read_response_headers();
if ($code eq '200') {
my $bufm;
while (1) {
my $buf;
my $nread = $nh->read_entity_body($buf, 1024);
die "read failed: $!" unless defined $nread;
last unless $nread;
$bufm .= $buf;
}
return $bufm if ($bufm);
} else {
print "ERROR: failed, code: $code, response: $mess\n";
}
return;
}
1;
@zembutsu

This comment has been minimized.

Copy link
Owner Author

commented May 1, 2014

push must do information to correspond to /serf/ beforehand on kvs of etcd.
In addition, this script does not support the registration of the setting information for etcd.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.