#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Mathias Kettner 2014             mk@mathias-kettner.de |
# +------------------------------------------------------------------+
#
# This file is part of Check_MK.
# The official homepage is at http://mathias-kettner.de/check_mk.
#
# check_mk is free software;  you can redistribute it and/or modify it
# under the  terms of the  GNU General Public License  as published by
# the Free Software Foundation in version 2.  check_mk is  distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
# out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
# PARTICULAR PURPOSE. See the  GNU General Public License for more de-
# ails.  You should have  received  a copy of the  GNU  General Public
# License along with GNU Make; see the file  COPYING.  If  not,  write
# to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
# Boston, MA 02110-1301 USA.

# Monitors FTP backup spaces of plesk domains.
# Data format
#
# <<<plesk_backups>>>
# <domain> <age-of-newest-file> <size-of-newest-file> <total-size>

import MySQLdb, sys, datetime, time, os
from ftplib import FTP

def connect():
    try:
        return MySQLdb.connect(
	    host    = 'localhost',
            db      = 'psa',
            user    = 'admin',
            passwd  = file('/etc/psa/.psa.shadow').read().strip(),
            charset = 'utf8',
        )
    except MySQLdb.Error, e:
        sys.stderr.write("MySQL-Error %d: %s\n" % (e.args[0], e.args[1]))
        sys.exit(1)

def get_domains():
    global db
    cursor = db.cursor()
    cursor2 = db.cursor()

    cursor.execute('SELECT id, name FROM domains')
    domains = {}
    for domain_id, domain in cursor.fetchall():
        cursor2.execute('SELECT param, value FROM BackupsSettings '
                        'WHERE id = %d AND type = \'domain\'' % domain_id)
        params = dict(cursor2.fetchall())
        domains[domain] = params

    cursor2.close()
    cursor.close()
    return domains

#
# MAIN
#

db = connect()

# 1. Virtual Hosts / Domains auflisten
# 2. Backupkonfiguration herausfinden
domains = get_domains()

# 3. Per FTP verbinden
#   4. Alter und Größe der neuesten Datei herausfinden
#   5. Größe aller Dateien in Summe herausfinden
#
# 6. Neuer Monat?
#   7. Auf FTP neues Verzeichnis anlegen: <kunde>_2012<monat>
#   8. Konfiguration in Plesk anpassen
output = ['<<<plesk_backups>>>']
for domain, p in domains.iteritems():
    try:
        if not p:
            output.append('%s 4' % domain) # Backup nicht konfiguriert
            continue

        ftp = FTP(
            p['backup_ftp_settinghost'],
            p['backup_ftp_settinglogin'],
            p['backup_ftp_settingpassword']
        )

        # Zeilen holen
        files = []
        ftp.retrlines(
            'LIST %s' % p['backup_ftp_settingdirectory'],
            callback = files.append
        )
        # example line:
        # -rw----r--   1 b091045  cust     13660160 Dec  3 01:50 bla_v8_bla-v8.bla0.net_1212030250.tar

        # Zeilen formatieren
        last_backup = None
        backups     = []
        for line in files:
            parts = line.split()
            if parts[-1].endswith('.tar'):
                dt = datetime.datetime(*time.strptime(parts[-1][-14:-4], '%y%m%d%H%M')[0:5])
                backup = (parts[-1], dt, int(parts[-5]))

                if not last_backup or dt > last_backup[1]:
                    last_backup = backup
                backups.append(backup)

        if not backups:
            output.append('%s 5' % domain) # Keine Sicherungen vorhanden
            continue

        # Get total size of all files on FTP
        f = []
        def get_size(base_dir, l = None):
            if l and l.split()[-1] in ['.', '..']:
                return 0

            size = 0
            if not l or l[0] == 'd':
                subdir = l and '/' + l.split()[-1] or ''
                dir_files = []
                ftp.retrlines('LIST %s%s' % (base_dir, subdir),
                    callback = dir_files.append
                )
                for line in dir_files:
                    size += get_size('%s%s' % (base_dir, subdir), line)
            else:
                size += int(l.split()[-5])
            return size
        total_size = get_size('')

        output.append('%s 0 %s %d %d' % (domain, last_backup[1].strftime('%s'), last_backup[2], total_size))

    except Exception, e:
        output.append('%s 2 %s' % (domain, e))

# Write cache and output
print '\n'.join(output)
