#!/usr/bin/env perl
use JSON qw(decode_json);
use Sys::Hostname;
use Getopt::Long;
use strict;
use warnings;

my @services;
my $verbose;
my $version;
my $releasetype;
my $clusterid;
my $adminsock;
my $socketdir;
my $service;
my @alarms;
my @checked;

GetOptions (
    "service=s{1}"  => \@services,
    "verbose"       => \$verbose,
    "version=s"     => \$version,
    "releasetype=s" => \$releasetype,
    "clusterid=s"   => \$clusterid,
);
help() if (not @services or (not defined $version) or (not defined $releasetype));

if($clusterid) {
    $socketdir = "/var/run/ceph/$clusterid/";
} else {
    $socketdir = "/var/run/ceph/";
}

# This bit of magic makes this script 'discover' running OSDs.
if (scalar(@services) == 1 and $services[0] eq "osd_discover") {
    if (not opendir(DIR, "$socketdir")) {
        push @alarms, "Can't readdir() $socketdir: $!";
    } else {
        @services = ();
        foreach my $dent (readdir(DIR)) {
            next if $dent !~ m#ceph\-(osd\.\d+)\.asok#;
            push @services, $1;
        }
        closedir(DIR);
        push @alarms, "No OSDs were discovered!" if (not scalar(@services));
    }
}

foreach $service (@services) {
  if($verbose) { print "running loop service $service\n"; }

    push @checked, "$service";
    if($clusterid) {
        $adminsock = "/var/run/ceph/$clusterid/ceph-$service.asok";
    } else {
        $adminsock = $service;
    }

    if ($service =~ m#^mgr\..+# and $clusterid){
        if (not opendir(DIR, "/var/run/ceph/$clusterid/")) {
            push @alarms, "Can't readdir() /var/run/ceph/$clusterid: $!";
        } else {
            foreach my $dent (readdir(DIR)) {
                next if $dent !~ m#ceph\-mgr\..+\.asok#;
                $adminsock = "/var/run/ceph/$clusterid/$dent";
            }
        }
    }



    if($verbose) { print "running command: /usr/bin/ceph daemon $adminsock version 2>&1\n"; }
    my $json = `/usr/bin/ceph daemon $adminsock version 2>&1`;
    my $json_out = eval { decode_json($json) };

    # If not valid JSON, then set alarm
    if ($@) {
      push @alarms, "NOT-RUNNING: $service";
      next;
    }

    if ($json_out->{version} ne $version) {
      push @alarms, "INVALID-VERSION: $service";
    }

    if ($json_out->{release_type} ne $releasetype) {
      push @alarms, "INVALID-RELEASETYPE: $service";
    }
}

if (@alarms) {
  my $brokenServices = join(' ', @alarms);
  print "CRITICAL - $brokenServices\n";
  exit 2;
} 

my $checkedServices = join(' ', @checked);
print "OK - Checked: $checkedServices \n";
exit 0;

#
##
#

sub help {
  print "Usage: $0 --service=\$SERVICE.\$ID --service=\$SERVICE.\$ID --verbose --version=X.X.X --releasetype=NAME\n";
  exit 1;
}

