Instantly share code, notes, and snippets.

Embed
What would you like to do?
#!/usr/bin/perl
use strict;
use LWP::Simple;
use JSON;
use IO::Socket;
use Env qw(RABBITMQ_LOCAL RABBITMQ_OTHER RABBITMQ_USER RABBITMQ_PASS RABBITMQ_NODE_NAME);
sub print_headers {
my $st = shift;
print "Status: $st\n";
print "Content-type: text/plain\n\n";
}
sub fail($) {
my $reason = shift;
print_headers("404 Not Found");
print "FAIL: $reason";
exit(0);
}
sub pass {
print_headers("200 OK");
print "PASS";
exit(0);
}
sub node_up($) {
my $host = shift;
# connect to Rabbit server
my $sock = new IO::Socket::INET ( PeerAddr => $host, PeerPort => '5672', Proto => 'tcp', Timeout => 1);
return 0 unless $sock;
# send the protocol header, await a Connection Start packet
print $sock "AMQP\x{00}\x{00}\x{09}\x{01}";
my $ret = $sock->recv($_, 7); # Type (C), Channel (n), Length (N)
my $command;
$sock->recv($command, 4); # Class (n), Method (n)
close($sock);
my $class_method = unpack("nn", $command);
return ($class_method == (10,10)); # Connection = 10, Start = 10
}
sub home_node() {
my $contents = get("http://$RABBITMQ_USER:$RABBITMQ_PASS\@$RABBITMQ_LOCAL:15672/api/queues");
return 0 unless $contents;
my $data = decode_json($contents);
my ($my_queues, $total_queues);
$my_queues = $total_queues = 0;
for (my $i = 0; $i < @$data; $i++) {
if ($RABBITMQ_NODE_NAME eq @{$data}[$i]->{node}) {
$my_queues++;
}
$total_queues++;
}
my $quorum = int($total_queues / 2);
if ($my_queues >= $quorum) {
return 1;
} else {
return 0;
}
}
if (node_up($RABBITMQ_LOCAL) != 1) {
fail("Node down");
} elsif (home_node() == 1) {
pass();
} elsif (node_up($RABBITMQ_OTHER) != 1) {
pass();
} else {
fail("Not home, other node up");
}
# Configuration for the Load Balancer Checker
SetEnv RABBITMQ_USER adminuser
SetEnv RABBITMQ_PASS adminpassword
SetEnv RABBITMQ_LOCAL rabbitmq1.mydomain
SetEnv RABBITMQ_OTHER rabbitmq2.mydomain
SetEnv RABBITMQ_NODE_NAME rabbit@rabbitmq1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment