#!/bin/bash

# ==========================================
# KONFIGURASI
# ==========================================
LOG_FILE="/var/log/setup_raid_ubuntu.log"
SOURCE_URL="http://eth0.my.id/exabytes"
# Target Folder Ubuntu (beda dengan CentOS)
TARGET_DIR="/usr/lib/nagios/plugins"

# Redirect output ke layar & log
exec > >(tee -a "$LOG_FILE") 2>&1

echo "#######################################################"
echo "STARTING RAID SETUP (UBUNTU CUSTOM) - $(date)"
echo "#######################################################"

# ==========================================
# STEP 1: PREPARE DIRECTORY & DEPENDENCIES
# ==========================================
echo "[STEP 1] Installing Dependencies..."

apt-get update
# Install paket wajib: Alien (buat convert rpm), libncurses, dll
apt-get install zip unzip alien libncurses6 libncursesw6 nagios-plugins nagios-plugins-basic nagios-plugins-standard curl wget -y

# Buat folder target
mkdir -p $TARGET_DIR
cd $TARGET_DIR

echo "Dependencies Installed."

# ==========================================
# STEP 2: INSTALL MEGACLI (ALIEN CONVERT)
# ==========================================
echo "[STEP 2] Installing MegaCLI..."

# Download MegaCLI Zip
wget ${SOURCE_URL}/8-07-14_MegaCLI.zip
unzip -o 8-07-14_MegaCLI.zip

# Masuk folder Linux
cd Linux

# Convert RPM ke DEB
echo "--> Converting RPM to DEB (Please wait)..."
alien --scripts MegaCli-8.07.14-1.noarch.rpm

# Install file .deb hasil convert
dpkg -i megacli_*.deb

# Kembali ke target dir & bersihkan sampah
cd $TARGET_DIR
rm -rf $TARGET_DIR/8-07-14_MegaCLI.zip $TARGET_DIR/Linux $TARGET_DIR/Windows $TARGET_DIR/FreeBSD $TARGET_DIR/Solaris

# Symlink MegaCLI (Agar check_lsi bisa menemukannya)
ln -sf /opt/MegaRAID/MegaCli/MegaCli64 /usr/bin/megacli
ln -sf /opt/MegaRAID/MegaCli/MegaCli64 /usr/bin/MegaCli64
# Script asli check_lsi kamu mencari di /opt/MegaRAID/MegaCli/MegaCli64, jadi aman.

echo "MegaCLI Installed via Alien."

# ==========================================
# STEP 3: CREATE CHECK_LSI (EMBEDDED)
# ==========================================
echo "[STEP 3] Creating check_lsi script..."

cd $TARGET_DIR

# Menulis file check_lsi dari konten yang kamu upload
cat > check_lsi <<'EOF'
#!/usr/bin/perl -w

# check_megaraid_sas Nagios plugin
# Copyright (C) 2007  Jonathan Delgado, delgado@molbio.mgh.harvard.edu
# Modified for user requirements

use strict;
use Getopt::Std;
#use lib qw(/usr/local/nagios/libexec /usr/local/nagios/libexec); # possible pathes to your Nagios plugins and utils.pm
use lib qw(/usr/lib64/nagios/plugins /usr/lib64/nagios/plugins); # possible pathes to your Nagios plugins and utils.pm
use utils qw(%ERRORS);

our($opt_h, $opt_s, $opt_o, $opt_m, $opt_p);


getopts('hs:o:p:m:');

if ( $opt_h ) {
        print "Usage: $0 [-s number] [-m number] [-o number]\n";
        print "       -s is how many hotspares are attached to the controller\n";
        print "       -m is the number of media errors to ignore\n";
        print "       -p is the predictive error count to ignore\n";
        print "       -o is the number of other disk errors to ignore\n";
        exit;
}

my $megaclibin = '/opt/MegaRAID/MegaCli/MegaCli64';  # the full path to your MegaCli binary
my $megacli = "sudo $megaclibin";      # how we actually call MegaCli
my $megapostopt = '-NoLog';            # additional options to call at the end of MegaCli arguments

my ($adapters);
my $hotspares = 0;
my $hotsparecount = 0;
my $pdbad = 0;
my $pdcount = 0;
my $mediaerrors = 0;
my $mediaallow = 0;
my $prederrors = 0;
my $predallow = 0;
my $othererrors = 0;
my $otherallow = 0;
my $result = '';
my $status = 'OK';

sub max_state ($$) {
        my ($current, $compare) = @_;

        if (($compare eq 'CRITICAL') || ($current eq 'CRITICAL')) {
                return 'CRITICAL';
        } elsif ($compare eq 'OK') {
                return $current;
        } elsif ($compare eq 'WARNING') {
                return 'WARNING';
        } elsif (($compare eq 'UNKNOWN') && ($current eq 'OK')) {
                return 'UNKNOWN';
        } else {
                return $current;
        }
}

sub exitreport ($$) {
        my ($status, $message) = @_;

        print STDOUT "$status: $message\n";
        exit $ERRORS{$status};
}


if ( $opt_s ) {
        $hotspares = $opt_s;
}
if ( $opt_m ) {
        $mediaallow = $opt_m;
}
if ( $opt_p ) {
        $predallow = $opt_p;
}
if ( $opt_o ) {
        $otherallow = $opt_o;
}

# Some sanity checks that you actually have something where you think MegaCli is
(-e $megaclibin)
        || exitreport('UNKNOWN',"error: $megaclibin does not exist");

# Get the number of RAID controllers we have
open (ADPCOUNT, "$megacli -adpCount $megapostopt |")
        || exitreport('UNKNOWN',"error: Could not execute $megacli -adpCount $megapostopt");

while (<ADPCOUNT>) {
        if ( m/Controller Count:\s*(\d+)/ ) {
                $adapters = $1;
                last;
        }
}
close ADPCOUNT;

ADAPTER: for ( my $adp = 0; $adp < $adapters; $adp++ ) {
        # Get the number of logical drives on this adapter
        open (LDGETNUM, "$megacli -LdGetNum -a$adp $megapostopt |")
                || exitreport('UNKNOWN', "error: Could not execute $megacli -LdGetNum -a$adp $megapostopt");

        my ($ldnum);
        while (<LDGETNUM>) {
                if ( m/Number of Virtual drives configured on adapter \d:\s*(\d+)/i ) {
                        $ldnum = $1;
                        last;
                }
        }
        close LDGETNUM;

        LDISK: for ( my $ld = 0; $ld < $ldnum; $ld++ ) {
                # Get info on this particular logical drive
                open (LDINFO, "$megacli -LdInfo -L$ld -a$adp $megapostopt |")
                        || exitreport('UNKNOWN', "error: Could not execute $megacli -LdInfo -L$ld -a$adp $megapostopt ");

                my ($size, $unit, $raidlevel, $ldpdcount, $state, $spandepth);
                while (<LDINFO>) {
                        if ( m/Size\s*:\s*((\d+\.?\d*)\s*(MB|GB|TB))/ ) {
                                $size = $2;
                                $unit = $3;
                                # Adjust MB to GB if that's what we got
                                if ( $unit eq 'MB' ) {
                                        $size = sprintf( "%.0f", ($size / 1024) );
                                        $unit= 'GB';
                                }
                        } elsif ( m/State\s*:\s*(\w+)/ ) {
                                $state = $1;
                                if ( $state ne 'Optimal' ) {
                                        $status = 'CRITICAL';
                                }
                        } elsif ( m/Number Of Drives\s*(per span\s*)?:\s*(\d+)/ ) {
                                $ldpdcount = $2;
                        } elsif ( m/Span Depth\s*:\s*(\d+)/ ) {
                                $spandepth = $1;
                        } elsif ( m/RAID Level\s*: Primary-(\d)/ ) {
                                $raidlevel = $1;
                        }
                }
                close LDINFO;

                # Report correct RAID-level and number of drives in case of Span configurations
                if ($ldpdcount && $spandepth > 1) {
                        $ldpdcount = $ldpdcount * $spandepth;
                        if ($raidlevel < 10) {
                                $raidlevel = $raidlevel . "0";
                        }
                }

                $result .= "$adp:$ld:RAID-$raidlevel:$ldpdcount drives:$size$unit:$state ";

        } #LDISK
        close LDINFO;

        # Get info on physical disks for this adapter
        open (PDLIST, "$megacli -PdList  -a$adp $megapostopt |")
                || exitreport('UNKNOWN', "error: Could not execute $megacli -PdList -a$adp $megapostopt ");

        my ($slotnumber,$fwstate);
        PDISKS: while (<PDLIST>) {
                if ( m/Slot Number\s*:\s*(\d+)/ ) {
                        $slotnumber = $1;
                        $pdcount++;
                } elsif ( m/(\w+) Error Count\s*:\s*(\d+)/ ) {
                        if ( $1 eq 'Media') {
                                $mediaerrors += $2;
                        } else {
                                $othererrors += $2;
                        }
                } elsif ( m/Predictive Failure Count\s*:\s*(\d+)/ ) {
                        $prederrors += $1;
                } elsif ( m/Firmware state\s*:\s*(\w+)/ ) {
                        $fwstate = $1;
                        if ( $fwstate eq 'Hotspare' ) {
                                $hotsparecount++;
                        } elsif ( $fwstate eq 'Online' ) {
                                # Do nothing
                        } elsif ( $fwstate eq 'Unconfigured' ) {
                                # A drive not in anything, or a non drive device
                                $pdcount--;
                        } elsif ( $slotnumber != 255 ) {
                                $pdbad++;
                                $status = 'CRITICAL';
                        }
                }
        } #PDISKS
        close PDLIST;
}

$result .= "Drives:$pdcount ";

# Any bad disks?
if ( $pdbad ) {
        $result .= "$pdbad Bad Drives ";
}

my $errorcount = $mediaerrors + $prederrors + $othererrors;
# Were there any errors?
if ( $errorcount ) {
        $result .= "($errorcount Errors) ";
        if ( ( $mediaerrors > $mediaallow ) ||
             ( $prederrors > $predallow )   ||
             ( $othererrors > $otherallow ) ) {
                $status = max_state($status, 'WARNING');
        }
}

# Do we have as many hotspares as expected (if any)
if ( $hotspares ) {
        if ( $hotsparecount < $hotspares ) {
                $status = max_state($status, 'WARNING');
                $result .= "Hotspare(s):$hotsparecount (of $hotspares)";
        } else {
                $result .= "Hotspare(s):$hotsparecount";
        }
}

exitreport($status, $result);
EOF

# --- AUTO FIX UNTUK UBUNTU ---
# File yang kamu kasih pakai path /usr/lib64/nagios/plugins (CentOS Style)
# Sedangkan Ubuntu pakai /usr/lib/nagios/plugins
# Kita replace otomatis agar utils.pm ketemu dan script tidak error.
sed -i 's|/usr/lib64/nagios/plugins|/usr/lib/nagios/plugins|g' check_lsi

chmod +x check_lsi
echo "check_lsi Setup Done."

# ==========================================
# STEP 4: FIX LIBNCURSES (LEGACY FIX)
# ==========================================
echo "[STEP 4] Fixing Libncurses Symlinks..."
cd /lib/x86_64-linux-gnu
ln -sf libncurses.so.6 libncurses.so.5
ln -sf libncursesw.so.6 libncursesw.so.5
echo "Libncurses Fixed."

# ==========================================
# STEP 5: CREATE SC.SH (TRANSPORTER)
# ==========================================
echo "[STEP 5] Creating sc.sh..."

cd $TARGET_DIR
cat > sc.sh <<'EOF'
#!/bin/bash
# collect hostname, ip, and RAID status
cat1=`curl -s ifconfig.me`;
cat2=`/usr/lib/nagios/plugins/check_lsi`;
cat3=`date +%d-%m-%Y--%H-%M`;
echo "$cat3,$HOSTNAME,$cat1,$cat2" > /usr/lib/nagios/plugins/$HOSTNAME.RAID.cat;
#
curl -X POST -F "file=@$HOSTNAME.RAID.cat" -k https://zero.idcloudhosting.my.id/guguk/
EOF

chmod +x sc.sh
echo "sc.sh Created."

# ==========================================
# STEP 5.5: INSTALL FTP 
# ==========================================
echo "[STEP 5.5] Installing FTP..."
# Install ftp 
apt-get install ftp -y
echo "FTP Installed."

# ==========================================
# STEP 6: SETUP CRONTAB
# ==========================================
echo "[STEP 6] Adding Cronjob..."

# Command cron
CRON_CMD="*/5 * * * * cd /usr/lib/nagios/plugins; bash sc.sh > /dev/null"

# Cek & Tambah ke crontab root
(crontab -l 2>/dev/null | grep -v "sc.sh"; echo "$CRON_CMD") | crontab -

echo "#######################################################"
echo "UBUNTU RAID SETUP COMPLETED!"
echo "Log: $LOG_FILE"
echo "#######################################################"