__init__.py 3.74 KB
import sys
import os
from configparser import ConfigParser
from logging import getLogger
from datetime import datetime
from subprocess import (
    Popen,
    PIPE,
    )
from sqlalchemy import engine_from_config
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from zope.sqlalchemy import register
import transaction
from maintenance.logger import setup_logging
from maintenance.daemon import (
    read_pid_file,
    write_pid_file,
    is_live,
    )
from .models import (
    Base,
    VPN,
    )


def out(s):
    print(s)
    sys.exit()


def init_db(argv=sys.argv[1:]):
    conf_file = argv[0]
    conf = ConfigParser()
    conf.read(conf_file)
    cf = dict(conf.items('main'))
    engine = engine_from_config(cf, 'sqlalchemy.')
    Base.metadata.create_all(engine)


def get_ipp_file():
    files = ['/etc/openvpn/ipp.txt', '/var/log/openvpn/ipp.txt']
    for filename in files:
        if os.path.exists(filename):
            return filename


def get_db_session(engine):
    factory = sessionmaker(bind=engine)
    db_session = factory()
    register(db_session)
    return db_session


def ping(ip: str) -> bool:
    cmd1 = ['ping', '-c1', '-w', '2', ip]
    cmd2 = ['grep', 'received']
    cmd3 = ['cut', '-f4', '-d', ' ']
    p1 = Popen(cmd1, stdout=PIPE)
    p2 = Popen(cmd2, stdin=p1.stdout, stdout=PIPE)
    p3 = Popen(cmd3, stdin=p2.stdout, stdout=PIPE)
    stdout, stderr = p3.communicate()
    n = stdout.decode('utf-8').rstrip()
    return n == '1'


def init_ip(argv=sys.argv[1:]):
    conf_file = argv[0]
    setup_logging(conf_file)
    log = getLogger()
    conf = ConfigParser()
    conf.read(conf_file)
    cf = dict(conf.items('main'))
    engine = engine_from_config(cf, 'sqlalchemy.')
    ipp_file = get_ipp_file()
    db_session = get_db_session(engine)
    base_q = db_session.query(VPN)
    with open(ipp_file) as f:
        for line in f.readlines():
            nama, ip = line.strip().split(',')[:2]
            i = int(ip.split('.')[-1])
            i += 2
            ip = '.'.join(ip.split('.')[:-1]) + '.%d' % i
            q = base_q.filter_by(ip=ip)
            row = q.first()
            if row:
                continue
            terhubung = ping(ip)
            row = VPN(nama=nama, ip=ip, terhubung=terhubung)
            with transaction.manager:
                db_session.add(row)
            log.info(
                f'{nama} {ip} sudah ditambahkan, konektivitas {terhubung}')


def main(argv=sys.argv[1:]):
    conf_file = argv[0]
    conf = ConfigParser()
    conf.read(conf_file)
    cf = dict(conf.items('main'))
    pid_file = cf['pid_file']
    pid = read_pid_file(pid_file)
    if pid and is_live(pid):
        out(f'PID saya {pid} masih aktif.')
    write_pid_file(pid_file)
    setup_logging(conf_file)
    log = getLogger()
    engine = engine_from_config(cf, 'sqlalchemy.')
    factory = sessionmaker(bind=engine)
    db_session = factory()
    register(db_session)
    q = db_session.query(VPN)
    for row in q.order_by(VPN.ip):
        status_lalu = row.terhubung
        cmd1 = ['ping', '-c1', '-w', '2', row.ip]
        cmd2 = ['grep', 'received']
        cmd3 = ['cut', '-f4', '-d', ' ']
        p1 = Popen(cmd1, stdout=PIPE)
        p2 = Popen(cmd2, stdin=p1.stdout, stdout=PIPE)
        p3 = Popen(cmd3, stdin=p2.stdout, stdout=PIPE)
        stdout, stderr = p3.communicate()
        n = stdout.decode('utf-8').rstrip()
        status_kini = n == '1'
        status_kini = ping(row.ip)
        if status_lalu == status_kini:
            continue
        msg = f'{row.nama} {row.ip} konektivitas: {status_lalu} -> '\
              f'{status_kini}'
        log.info(msg)
        row.terhubung = status_kini
        row.perubahan = datetime.now()
        with transaction.manager:
            db_session.add(row)