Skip to content

Status eines remote Servers mittels ssh auslesen und kritische Zustände alarmieren

walldi edited this page Jan 6, 2017 · 11 revisions

Python Lib paramiko für die SSH-Kommunikation installieren:

sudo apt-get install build-essential libssl-dev libffi-dev python-dev
pip install paramiko

item.conf:

[server]
 [[smarthome_local]]
  [[[loadavg]]]
    type = list
    ssh_cmd_pull = 'cat /proc/loadavg'
    ssh_host = 'localhost'
    ssh_user = 'smarthome'
    ssh_passwd = 'smarthome'
    [[[[avg1min]]]]
      type = num
      eval = sh...()[0]
      eval_trigger = ..
    [[[[avg5min]]]]
      type = num
      eval = sh...()[1]
      eval_trigger = ..
        [[[[avg15min]]]]
        type = num
        eval = sh...()[2]
        eval_trigger = ..
    [[[[alarm1]]]]
      name = 'Load Avg 5min > 1.0!'
      type = bool
      eval = sh...avg5min() > 1.0
      eval_trigger = ..avg5min
    [[[[alarm2]]]]
      name = 'Load Avg 5min > 2.0!'
      type = bool
      eval = sh...avg5min() > 2.0
      eval_trigger = ..avg5min
    [[[[alarm3]]]]
      name = 'Load Avg 5min > 1.0!'
      type = bool
      eval = sh...avg5min() > 3.0
      eval_trigger = ..avg5min

      [[[uptime]]]
        type = list
        ssh_cmd_pull = 'cat /proc/uptime'
        ssh_host = 'smarthome'
        ssh_user = 'smarthome'
        ssh_passwd = 'smarthome'
        [[[[s]]]]
          type = num
          eval = sh...()[0]
          eval_trigger = ..
        [[[[days]]]]
          type = num
          eval =  int(sh...s() / 60 / 60 / 24)
          eval_trigger = ..s
        [[[[hours]]]]
          type = num
          eval =  int((sh...s() - sh...days() * 24 * 60 * 60) / 60 / 60)
          eval_trigger = ..s
        [[[[mins]]]]
          type = num
          eval =  int((int(sh...s()) - int(sh...days()) * 24 * 60 * 60 - int(sh...hours()) * 60 * 60 ) / 60)
          eval_trigger = ..s

        [[[[pretty]]]]
          name = days_hours_min_secs
          type = str
          eval = "{0}days {1}hours {2}minutes".format(sh...days(), sh...hours(), sh...mins())
          eval_trigger = ..s
        [[[[alarm]]]]
          name = 'Server reboot last 5min!!!'
          type = bool
          eval = sh...s() < 300
          eval_trigger = ..s

etc/logic.conf

[sshserver]
    filename = sshserver.py
    cycle = 300

logics/sshserver.conf

#!/usr/bin/env python
#
# (c) Dirk Wallmeier
#
logger.info("Logik SSH_Server : by :" + trigger['by'] )
#logger.info("Logik SSH_Server : source :" + trigger['source'] )
#logger.info("Logik SSH_Server : dest :" + trigger['dest'] )
#logger.info("Logik SSH_Server : value :" + trigger['value'] )

DEFAULT_KEY_PATH = "~/.ssh/id_rsa"

import paramiko

ssh_hosts = {}
for item in sh.find_items('ssh_host'):    # findet alle Items die ein Attribut 'ssh_host' besitzen
    host = item.conf['ssh_host']
    user = item.conf['ssh_user']
    passwd = item.conf['ssh_passwd']
    #key = item.conf['ssh_key']
    #key = ''
    #if not passwd or key:
    #        rsakey = paramiko.RSAKey.from_private_key_file(os.path.expanduser(key or DEFAULT_KEY_PATH))
    #else:
    #        rsakey = None

    #ssh_hosts[host] = {'user' : user, 'passwd': passwd, 'key': rsakey}
    ssh_hosts[host] = {'user' : user, 'passwd': passwd}


ssh = {}
for host in ssh_hosts.keys():  # connect to all hosts
    ssh[host] = paramiko.SSHClient()
    ssh[host].set_missing_host_key_policy( paramiko.AutoAddPolicy())
    ssh[host].connect(host, username=ssh_hosts[host]['user'], password=ssh_hosts[host]['passwd'],) #key=rsakey)

# cat /proc/uptime
# 1516600.94 2900685.66
# cat /proc/loadavg
# 0.10 0.16 0.17 1/167 8686

if trigger['by'] == 'Scheduler':   # scheduler / cycle ??

    for item in sh.find_items('ssh_cmd_pull'):    # findet alle Items die ein Attribut 'ssh_cmd' besitzen und \
                                                  # führe cmd auf remote host aus
        cmd = item.conf['ssh_cmd_pull']
        host = item.conf['ssh_host']
        stdin, stdout, stderr = ssh[host].exec_command(cmd)
        res = stdout.readlines()
        logger.info("Logik SSH_Server : {0} : {1}".format(cmd, res[0].split(' ')[0]) )
        item(res[0].split(' '))
elif trigger['by'] == 'fdhahsdf':  # watchitem ??
    item = sh.return_item(trigger['source'])
    cmd = item.conf['ssh_cmd_push']
    host = item.conf['ssh_host']
    stdin, stdout, stderr = ssh[host].exec_command(cmd)
    stdout.readlines()
    item(0)