diff --git a/prtg-proxmox-aio.bash b/prtg-proxmox-aio.bash new file mode 100644 index 0000000..7322946 --- /dev/null +++ b/prtg-proxmox-aio.bash @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +# + +echo "Starting sensor setup." + +monidir="/opt/monitoring" +snmpdconf="/etc/snmp/snmpd.conf" + +mkdir -p "$monidir" + +# Install snmp & snmpd +if apt install -y smartmontools snmp snmpd tmux vim && systemctl enable --now snmpd; then + echo "SmartMonTools, SNMP, SNMPD, tmux & vim installed." +else + echo "Something went wrong during installation of smartmontools, snmp, snmpd, tmux & vim." + exit 1 +fi + +# Configure snmpd +if grep -E '\brocommunity\b' "$snmpdconf" | grep -v 'rocommunity:' | grep -v public; then + echo "rocommunity password already set, check line above for details." +else + read -p "Enter the rocommunity password: " rocompw + echo "rocommunity $rocompw" >> "$snmpdconf" +fi +sed -i 's/agentaddress.*/agentaddress udp:161/' "$snmpdconf" +sed -i 's/-u Debian-snmp/-u root/' /lib/systemd/system/snmpd.service +systemctl daemon-reload + +read -p "Install Ceph sensors? [y/n] " answer +case "$answer" in + [Yy]|[Yy][Ee][Ss]) + echo "Installing Ceph sensors." + + touch "$monidir"/snmp-ceph-free.bash + touch "$monidir"/snmp-ceph-used.bash + echo "Files touched." + + echo -e "#!/bin/bash +if [ \"\$1\" = \"-g\" ]; then + echo .1.3.6.1.2.1.25.1.8 + echo integer + ceph osd df | grep \"TOTAL\" | awk '{print \$12}' +fi +exit 0 +# EOF" > "$monidir"/snmp-ceph-free.bash + echo "snmp-ceph-free.bash written." + + echo -e "#!/bin/bash +if [ \"\$1\" = \"-g\" ]; then + echo .1.3.6.1.2.1.25.1.9 + echo gauge + ceph osd df | grep \"TOTAL\" | awk '{print \$14}' +fi +exit 0 +# EOF" > "$monidir"/snmp-ceph-used.bash + echo "snmp-ceph-used.bash written." + + chmod u+x $monidir/* + echo "Executable flags set." + + if grep -q ceph-free "$snmpdconf"; then + echo "snmp-ceph-free already added to $snmpdconf" + else + echo "pass .1.3.6.1.2.1.25.1.8 /bin/sh /opt/monitoring/snmp-ceph-free.bash" >> "$snmpdconf" + echo "Added snmp-ceph-free.bash to snmpd config." + fi + if grep -q ceph-used "$snmpdconf"; then + echo "snmp-ceph-used already added to $snmpdconf" + else + echo "pass .1.3.6.1.2.1.25.1.9 /bin/sh /opt/monitoring/snmp-ceph-used.bash" >> "$snmpdconf" + echo "Added snmp-ceph-used.bash to snmpd config." + fi + + systemctl restart snmpd + echo "ceph sensor configuration done." + ;; + [Nn]|[Nn][Oo]|*) + echo "Skipping Ceph sensors." + ;; +esac + +read -p "Install RAM sensor? [y/n] " answer +case "$answer" in + [Yy]|[Yy][Ee][Ss]) + echo "Installing RAM sensor." + touch "$monidir"/snmp-memusedpercent.bash + echo "File touched." + echo -e "#!/bin/bash +# +# Real Memory Percent Calculation +total=\"\$(cat /proc/meminfo | grep 'MemTotal' | awk '{print \$2}')\" +avail=\"\$(cat /proc/meminfo | grep 'MemAvailable' | awk '{print \$2}')\" + +used=\$((total - avail)) +prcnt=\$(( (used * 100) / total )) + +if [ \"\$1\" = \"-g\" ]; then + echo \".1.3.6.1.2.1.25.1.69\" + echo \"integer\" + echo \"\$prcnt\" +fi +exit 0 +# EOF" > "$monidir"/snmp-memusedpercent.bash + echo "snmp-memusedpercent.bash written." + chmod u+x $monidir/* + echo "Executable flags set." + + if grep -q memusedpercent "$snmpdconf"; then + echo "snmp-memusedpercent already added to $snmpdconf" + else + echo "pass .1.3.6.1.2.1.25.1.69 /bin/sh /opt/monitoring/snmp-memusedpercent.bash" >> "$snmpdconf" + echo "Added snmp-memusedpercent.bash to snmpd config." + fi + + systemctl restart snmpd + echo "RAM sensor configuration done." + ;; + [Nn]|[Nn][Oo]|*) + echo "Skipping RAM sensor." + ;; +esac + +read -p "Install SMART sensor? [y/n] " answer +case "$answer" in + [Yy]|[Yy][Ee][Ss]) + echo "Installing SMARTEST sensor." + + username="monitoring" + userhome="/home/$username" + + monidir="/opt/monitoring" + prtgdir="/var/prtg/scriptsxml" + + croncmd="/opt/monitoring/smartest.bash >> "$userhome"/prtg_smartest.log 2>&1" + crontime="0 * * * * $croncmd" + + # Create user + if useradd -m $username; then + echo "$username created" + # Set password + read -p "Enter password for the "$username" user: " password + echo "$username:$password" | chpasswd + echo "Password set" + else + echo "$username already exists" + fi + + # Create directories and files + mkdir -p $prtgdir + + # Create files in user home + touch $userhome/active_disks.txt + touch $userhome/excluded_disks.txt + touch $userhome/prtg_smartest.log + touch $userhome/prtgout.xml + touch $monidir/smartest.bash + touch $prtgdir/prtg_smartest.bash + echo "Files touched." + + # Change ownership of files + chown $username:$username $userhome/* + chown $username:$username $prtgdir/* + echo "Ownership changed." + + # Set executable flags + chmod u+x $prtgdir/* + chmod u+x $monidir/* + echo "Executable flags set." + + # Create crontab to check disks every hour + if crontab -l | grep smartest; then + echo "Cronjob already exists." + else + (crontab -l 2>/dev/null; echo "$crontime") | crontab - + echo "Cronjob created" + fi + + # Write prtg_smartest.bash + echo -e "#!/usr/bin/env bash +# +cat \"/home/monitoring/prtgout.xml\" +# EOF" > $prtgdir/prtg_smartest.bash + + echo "$prtgdir/prtg_smartest.bash written" + + # Write smartest.bash + echo -e "#!/usr/bin/env bash +# +#Proxmox SMART Monitoring for PRTG | v2.0 Mar 2025 | exaSys AG +# +channel_id=2 +output=\"/home/monitoring/prtgout.xml\" +log=\"/home/monitoring/prtg_smartest.log\" +active_disks=\"/home/monitoring/active_disks.txt\" +excluded_disks=\"/home/monitoring/excluded_disks.txt\" + +disk_count_real=\"\$(lsblk -d | tail -n +2 | wc -l)\" +disk_count_current=\"\$(cat \"\$active_disks\" | wc -l)\" + +if [ ! -f \"\$active_disks\" ] || [ ! -s \"\$active_disks\" ]; then + lsblk -d | awk '{print \$1}' | tail -n +2 > \"\$active_disks\" +elif [ \"\$disk_count_real\" -gt \"\$disk_count_current\" ]; then + lsblk -d | awk '{print \$1}' | tail -n +2 > \"\$active_disks\" + echo \"Disk(s) added\" >> \"\$log\" 2>&1 +else + echo \"\" > \"\$output\" + for disk in \$(cat \"\$active_disks\") + do + if grep \"\$disk\" \"\$excluded_disks\" >> \"\$log\" 2>&1; then + echo \"\$disk is excluded\" >> \"\$log\" 2>&1 + elif [[ \"\$disk\" == zd* ]]; then + echo \"\$disk is a ZFS device node, excluding\" >> \"\$log\" 2>&1 + elif [[ \"\$disk\" == rbd* ]]; then + echo \"\$disk is a Ceph device node, excluding\" >> \"\$log\" 2>&1 + else + smartresult=\$(/usr/sbin/smartctl -a /dev/\"\$disk\") + if grep -E \"OK|PASSED\" <<< \"\$smartresult\" >> \"\$log\" 2>&1; then + echo \"\$disk is okay\" >> \"\$log\" + echo -e \"\\\nchannel_\$channel_id\\\n\$disk SMART Status\\\n1\\\n0.5\\\nCustom\\\n\\\n1\\\n\" >> \"\$output\" + channel_id=\$((channel_id + 1)) + if grep -i \"Wear_Leveling_Count\" <<< \"\$smartresult\" >> \"\$log\" 2>&1; then + wlcresult=\$(/usr/sbin/smartctl -a /dev/\"\$disk\" | grep -i Wear_Leveling_Count | awk '{print \$4}' | sed 's/^0*//') + echo \"\$disk: \$wlcresult% Lifetime remaining\" >> \"\$log\" 2>&1 + echo -e \"\\\nchannel_\$channel_id\\\n\$disk WLC Lifetime\\\n1\\\n25\\\n10\\\nCustom\\\n%\\\n\$wlcresult\\\n\" >> \"\$output\" + channel_id=\$((channel_id + 1)) + else + echo \"\$disk: No WLC available\" >> \"\$log\" 2>&1 + fi + else + echo \"\$disk: SMART failed\" >> \"\$log\" 2>&1 + echo -e \"\\\nchannel_\$channel_id\\\n\$disk SMART Status\\\n1\\\n0.5\\\nCustom\\\n\\\n0\\\n\" >> \"\$output\" + fi + fi + done +fi +echo \"\" >> \"\$output\" +# EOF" > $monidir/smartest.bash + echo "$monidir/smartest.bash written." + chmod u+x $monidir/* + echo "Executable flags set." + + echo "SMART monitoring configuration done." + + # Exclude disks + read -p "Enter raw disk name to exclude (e.g. sr0) or leave empty: " exclude + if [[ -n $exclude ]]; then + echo "$exclude" >> "$userhome"/excluded_disks.txt + fi + echo "Exclusion disk list updated." + + # Execute smartest.bash to populate disk list + source /opt/monitoring/smartest.bash + source /opt/monitoring/smartest.bash + echo "Active disk list populated." + ;; + [Nn]|[Nn][Oo]|*) + echo "Skipping SMART sensor." + ;; +esac + +echo "All done." + +# EOF