Guest User

daemon_agent/daemon_agent/scripts/netcheck.py

a guest
Mar 21st, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.14 KB | None | 0 0
  1. import sys
  2. import os
  3. import subprocess
  4. if sys.version_info.major == 2:
  5.     from xmlrpclib import ServerProxy
  6. else:
  7.     from xmlrpc.client import ServerProxy
  8. import socket
  9. socket.setdefaulttimeout(10)
  10. import transaction
  11. import logging
  12. from sqlalchemy import engine_from_config
  13. from pyramid.paster import (
  14.     get_appsettings,
  15.     setup_logging,
  16.     bootstrap,
  17.     )
  18. from ..models import DBSession
  19. from ..models.services.conf import ConfService
  20. from ..models.network import (
  21.     NetConnection,
  22.     NetLog,
  23.     )
  24. from ..models.conf import Conf
  25.  
  26.  
  27. CONNECTED = 0
  28. DISCONNECTED = -1
  29. REFUSE = -2
  30.  
  31. log = logging.getLogger(__name__)
  32.  
  33.  
  34. def telnet(row):
  35.     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    
  36.     log.debug('telnet {ip} {port}'.format(ip=row.ip, port=row.port))
  37.     code = sock.connect_ex((row.ip, row.port))
  38.     return code in (0, 106)
  39.  
  40.  
  41. def netstat(row):
  42.     log.debug('netcat -nap | grep {ip}:{port}'.format(ip=row.ip, port=row.port))
  43.     c1 = ['netstat', '-nap']
  44.     c2 = ['grep', '{ip}:{port}'.format(ip=row.ip, port=row.port)]
  45.     p1 = subprocess.Popen(c1, stdout=subprocess.PIPE)
  46.     p2 = subprocess.Popen(c2, stdin=p1.stdout, stdout=subprocess.PIPE)
  47.     s = p2.communicate()[0]
  48.     if isinstance(s, bytes):
  49.         s = s.decode('utf-8')
  50.     return s.find('ESTABLISHED') > -1
  51.  
  52.  
  53.  
  54. class NetCheck:
  55.     def __init__(self, force=False):
  56.         self.force = force
  57.         self.username = ConfService.get_val('netcheck', 'username')
  58.         self.password = ConfService.get_val('netcheck', 'password')
  59.         self.url = ConfService.get_val('netcheck', 'url', 'https://h2h.opensipkd.com/rpc')
  60.         self.rpc = ServerProxy(self.url)
  61.  
  62.     def run(self):        
  63.         first_hosts = get_first_hosts()
  64.         for name in first_hosts:
  65.             self.ping_all(name)
  66.  
  67.     def ping(self, row):
  68.         if row.port:
  69.             for f in (netstat, telnet):
  70.                 if f(row):
  71.                     self.set_last_state(row, CONNECTED)
  72.                     return True
  73.         log.debug('ping {}'.format(row.ip))
  74.         c1 = ['ping', '-c1', '-w', '2', row.ip]
  75.         c2 = ['grep', 'received']
  76.         c3 = ['cut', '-f4', '-d', ' ']
  77.         p1 = subprocess.Popen(c1, stdout=subprocess.PIPE)
  78.         p2 = subprocess.Popen(c2, stdin=p1.stdout, stdout=subprocess.PIPE)
  79.         p3 = subprocess.Popen(c3, stdin=p2.stdout, stdout=subprocess.PIPE)
  80.         result = p3.communicate()
  81.         s = result[0]
  82.         if isinstance(s, bytes):
  83.             s = s.decode('utf-8')
  84.         s = s.strip()
  85.         connected = s == '1'
  86.         if connected:
  87.             if row.port:
  88.                 self.set_last_state(row, REFUSE)
  89.             else:
  90.                 self.set_last_state(row, CONNECTED)
  91.         else:
  92.             self.set_last_state(row, DISCONNECTED)
  93.         return connected
  94.  
  95.     def ping_all(self, name):
  96.         q = DBSession.query(NetConnection).filter_by(name=name)
  97.         row = q.first()
  98.         if self.ping(row):
  99.             self.set_gateway_connected(row)
  100.             return True
  101.         if row.gateway:
  102.             return self.ping_all(row.gateway)
  103.  
  104.     def set_gateway_connected(self, row):
  105.         if not row.gateway:
  106.             return
  107.         q = DBSession.query(NetConnection).filter_by(name=row.gateway)
  108.         row = q.first()
  109.         row.status_id = CONNECTED
  110.         DBSession.add(row)
  111.         DBSession.flush()
  112.         self.send_last_state(row)
  113.         self.set_gateway_connected(row)
  114.  
  115.     def set_last_state(self, row, status_id):
  116.         if row.status_id == status_id:
  117.             if self.force:
  118.                 self.send_last_state(row)
  119.         else:
  120.             self.set_state(row, status_id)
  121.             self.send_last_state(row)
  122.  
  123.     def set_state(self, row, status_id):
  124.         hist = NetLog()
  125.         hist.name = row.name
  126.         hist.ip = row.ip
  127.         hist.port = row.port
  128.         hist.status_id = status_id
  129.         DBSession.add(hist)
  130.         DBSession.flush()
  131.         row.status_id = status_id
  132.         row.updated = hist.created
  133.         DBSession.add(row)
  134.         DBSession.flush()
  135.  
  136.     def send_last_state(self, row):
  137.         if not self.username or not row.description:
  138.             return
  139.         p = {'username': self.username,
  140.              'password': self.password,
  141.              'description': row.description,
  142.              'ip': row.ip,
  143.              'status_id': row.status_id}
  144.         if row.port:
  145.             p['port'] = row.port
  146.         p_ = dict(p)
  147.         p_['password'] = '...'
  148.         log.debug('send net_status {url} {p}'.format(url=self.url, p=p_))
  149.         resp = self.rpc.net_status(p)
  150.         log.debug('recv net_status {r}'.format(r=resp))
  151.  
  152.  
  153. def get_first_hosts():
  154.     gateways = []
  155.     q = DBSession.query(NetConnection)
  156.     for row in q:
  157.         if row.gateway and row.gateway not in gateways:
  158.             gateways.append(row.gateway)
  159.     r = []
  160.     for row in q:
  161.         if row.name not in gateways:
  162.             r.append(row.name)
  163.     return r
  164.  
  165.  
  166. def distro():
  167.     cmd = ['lsb_release', '-a']
  168.     c = subprocess.Popen(cmd, stdout=subprocess.PIPE)
  169.     s = c.communicate()
  170.     s = s[0]
  171.     if isinstance(s, bytes):
  172.         s = s.decode('utf-8')
  173.     lines = s.split('\n')
  174.     d = {}
  175.     for line in lines:
  176.         items = line.split('\t')
  177.         if items[0] == 'Distributor ID:':
  178.             d['id'] = items[1]
  179.         elif items[0] == 'Codename:':
  180.             d['codename'] = items[1]
  181.         elif items[0] == 'Release:':
  182.             d['versi'] = float(items[1])
  183.         elif items[0] == 'Description:':
  184.             d['keterangan'] = items[1]
  185.     return d
  186.  
  187.  
  188. def update_distro(DBSession):
  189.     d = distro()
  190.     for nama in d:
  191.         q = DBSession.query(Conf).filter_by(grup='distro', nama=nama)
  192.         c = q.first()
  193.         if not c:
  194.             c = Conf()
  195.             c.grup = 'distro'
  196.             c.nama = nama
  197.         c.nilai = d[nama]
  198.         DBSession.add(c)
  199.     username = ConfService.get_val('netcheck', 'username')
  200.     if not username:
  201.         return
  202.     password = ConfService.get_val('netcheck', 'password')
  203.     url = ConfService.get_val('netcheck', 'url', 'https://h2h.opensipkd.com/rpc')
  204.     distro_ip = ConfService.get_val('distro','ip')
  205.     distro_nama = ConfService.get_val('distro','id')
  206.     distro_versi = ConfService.get_val('distro','versi')
  207.     distro_codename = ConfService.get_val('distro','codename')
  208.     rpc = ServerProxy(url)
  209.     p = {'username': username,
  210.          'password': password,
  211.          'ip': distro_ip,
  212.          'nama': distro_nama,
  213.          'versi': distro_versi,
  214.          'codename': distro_codename
  215.          }
  216.     p_ = dict(p)
  217.     p_['password'] = '...'
  218.     log.debug('send distro {url} {p}'.format(url = url, p=p_))
  219.     resp = rpc.distro(p)
  220.     log.debug('recv distro {r}'.format(r=resp))
  221.    
  222.  
  223.  
  224. def main(argv=sys.argv):
  225.     config_uri = argv[1]
  226.     force_sync = '--force' in argv
  227.     setup_logging(config_uri)
  228.     settings = get_appsettings(config_uri)
  229.     engine = engine_from_config(settings, 'sqlalchemy.')
  230.     DBSession.configure(bind=engine)
  231.     bootstrap(config_uri)
  232.     nc = NetCheck(force_sync)
  233.     nc.run()
  234.     update_distro(DBSession)
  235.     transaction.commit()
Add Comment
Please, Sign In to add comment