Skip to content

Instantly share code, notes, and snippets.

@zembutsu
Created May 1, 2014 04:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zembutsu/c01c4a152c3ac4be8950 to your computer and use it in GitHub Desktop.
Save zembutsu/c01c4a152c3ac4be8950 to your computer and use it in GitHub Desktop.
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
Copy link
Author

zembutsu 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