客户这里有一台linux服务器,作为dhcp服务器使用。每次需要查询dhcp地址分配记录的默认只能在 cat /var/lib/dhcpd/dhcpd.leases这个文件查看,查询起来非常不方便 就像这样

后来自己尝试编写脚本来解析,但是处理得不是很好。但是在githup搜寻到有一个大佬写的python脚本,可以完成解析统计,人性化了很多,就像这样

脚本如下:

#!/usr/bin/python
import datetime, bisect

def parse_timestamp(raw_str):
       tokens = raw_str.split()

       if len(tokens) == 1:
               if tokens[0].lower() == 'never':
                       return 'never';

               else:
                       raise Exception('Parse error in timestamp')

       elif len(tokens) == 3:
               return datetime.datetime.strptime(' '.join(tokens[1:]),
                       '%Y/%m/%d %H:%M:%S')

       else:
               raise Exception('Parse error in timestamp')


def timestamp_is_ge(t1, t2):
       if t1 == 'never':
               return True

       elif t2 == 'never':
               return False

       else:
               return t1 >= t2


def timestamp_is_lt(t1, t2):
       if t1 == 'never':
               return False

       elif t2 == 'never':
               return t1 != 'never'

       else:
               return t1 < t2


def timestamp_is_between(t, tstart, tend):
       return timestamp_is_ge(t, tstart) and timestamp_is_lt(t, tend)


def parse_hardware(raw_str):
       tokens = raw_str.split()

       if len(tokens) == 2:
               return tokens[1]

       else:
               raise Exception('Parse error in hardware')


def strip_endquotes(raw_str):
       return raw_str.strip('"')


def identity(raw_str):
       return raw_str


def parse_binding_state(raw_str):
       tokens = raw_str.split()

       if len(tokens) == 2:
               return tokens[1]

       else:
               raise Exception('Parse error in binding state')


def parse_next_binding_state(raw_str):
       tokens = raw_str.split()

       if len(tokens) == 3:
               return tokens[2]

       else:
               raise Exception('Parse error in next binding state')


def parse_rewind_binding_state(raw_str):
       tokens = raw_str.split()

       if len(tokens) == 3:
               return tokens[2]

       else:
               raise Exception('Parse error in next binding state')


def parse_leases_file(leases_file):
       valid_keys = {
               'starts':               parse_timestamp,
               'ends':                 parse_timestamp,
               'tstp':                 parse_timestamp,
               'tsfp':                 parse_timestamp,
               'atsfp':                parse_timestamp,
               'cltt':                 parse_timestamp,
               'hardware':             parse_hardware,
               'binding':              parse_binding_state,
               'next':                 parse_next_binding_state,
               'rewind':               parse_rewind_binding_state,
               'uid':                  strip_endquotes,
               'client-hostname':      strip_endquotes,
               'option':               identity,
               'set':                  identity,
               'on':                   identity,
               'abandoned':            None,
               'bootp':                None,
               'reserved':             None,
               }

       leases_db = {}

       lease_rec = {}
       in_lease = False
       in_failover = False

       for line in leases_file:
               if line.lstrip().startswith('#'):
                       continue

               tokens = line.split()

               if len(tokens) == 0:
                       continue

               key = tokens[0].lower()

               if key == 'lease':
                       if not in_lease:
                               ip_address = tokens[1]

                               lease_rec = {'ip_address' : ip_address}
                               in_lease = True

                       else:
                               raise Exception('Parse error in leases file')

               elif key == 'failover':
                       in_failover = True
               elif key == '}':
                       if in_lease:
                               for k in valid_keys:
                                       if callable(valid_keys[k]):
                                               lease_rec[k] = lease_rec.get(k, '')
                                       else:
                                               lease_rec[k] = False

                               ip_address = lease_rec['ip_address']

                               if ip_address in leases_db:
                                       leases_db[ip_address].insert(0, lease_rec)

                               else:
                                       leases_db[ip_address] = [lease_rec]

                               lease_rec = {}
                               in_lease = False

                       elif in_failover:
                               in_failover = False
                               continue
                       else:
                               raise Exception('Parse error in leases file')

               elif key in valid_keys:
                       if in_lease:
                               value = line[(line.index(key) + len(key)):]
                               value = value.strip().rstrip(';').rstrip()

                               if callable(valid_keys[key]):
                                       lease_rec[key] = valid_keys[key](value)
                               else:
                                       lease_rec[key] = True

                       else:
                               raise Exception('Parse error in leases file')

               else:
                       if in_lease:
                               raise Exception('Parse error in leases file')

       if in_lease:
               raise Exception('Parse error in leases file')

       return leases_db


def round_timedelta(tdelta):
       return datetime.timedelta(tdelta.days,
               tdelta.seconds + (0 if tdelta.microseconds < 500000 else 1))


def timestamp_now():
       n = datetime.datetime.utcnow()
       return datetime.datetime(n.year, n.month, n.day, n.hour, n.minute,
               n.second + (0 if n.microsecond < 500000 else 1))


def lease_is_active(lease_rec, as_of_ts):
       return timestamp_is_between(as_of_ts, lease_rec['starts'],
               lease_rec['ends'])


def ipv4_to_int(ipv4_addr):
       parts = ipv4_addr.split('.')
       return (int(parts[0]) << 24) + (int(parts[1]) << 16) + \
               (int(parts[2]) << 8) + int(parts[3])


def select_active_leases(leases_db, as_of_ts):
       retarray = []
       sortedarray = []

       for ip_address in leases_db:
               lease_rec = leases_db[ip_address][0]

               if lease_is_active(lease_rec, as_of_ts):
                       ip_as_int = ipv4_to_int(ip_address)
                       insertpos = bisect.bisect(sortedarray, ip_as_int)
                       sortedarray.insert(insertpos, ip_as_int)
                       retarray.insert(insertpos, lease_rec)

       return retarray


##############################################################################


myfile = open('/var/lib/dhcpd/dhcpd.leases', 'r')
leases = parse_leases_file(myfile)
myfile.close()

now = timestamp_now()
report_dataset = select_active_leases(leases, now)

print('+------------------------------------------------------------------------------')
print('| DHCPD ACTIVE LEASES REPORT')
print('+-----------------+-------------------+----------------------+-----------------')
print('| IP Address      | MAC Address       | Expires (days,H:M:S) | Client Hostname ')
print('+-----------------+-------------------+----------------------+-----------------')

for lease in report_dataset:
       print('| ' + format(lease['ip_address'], '<15') + ' | ' + \
               format(lease['hardware'], '<17') + ' | ' + \
               format(str((lease['ends'] - now) if lease['ends'] != 'never' else 'never'), '>20') + ' | ' + \
               lease['client-hostname'])

print('+-----------------+-------------------+----------------------+-----------------')
print('| Total Active Leases: ' + str(len(report_dataset)))
print('| Report generated (UTC): ' + str(now))
print('+------------------------------------------------------------------------------')

感觉运维工作,又轻松了点。。。

自己水平很low,学不动了,正所谓 我们不生产代码,只做代码界的搬运工。

之前也搜集了许多脚本,统一放在了自己代码库中

https://gitee.com/yashirochaos/yangchao

现在不会python的云计算工程师不是好网工 加油吧各位