Analysis of Linux DHCP server IP allocation Python script

Leymus chinensis 2021-07-20 04:42:17
analysis linux dhcp server ip


The customer has one here linux The server , As dhcp Server usage . Every time you need to query dhcp The default address assignment record can only be in cat /var/lib/dhcpd/dhcpd.leases View this file , It's very inconvenient to inquire
Just like this.

Later, I tried to write a script to parse , But it wasn't handled very well . But in githup I found a big man writing python Script , Can complete the analysis of Statistics , Humanized a lot , Just like this.

The script is as follows :

#!/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('+------------------------------------------------------------------------------')

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
  • 232.
  • 233.
  • 234.
  • 235.
  • 236.
  • 237.
  • 238.
  • 239.
  • 240.
  • 241.
  • 242.
  • 243.
  • 244.
  • 245.
  • 246.
  • 247.
  • 248.
  • 249.
  • 250.
  • 251.
  • 252.
  • 253.
  • 254.
  • 255.
  • 256.
  • 257.
  • 258.
  • 259.

I feel like the operation and maintenance work , Easy again ...

My level is very high low, I can't learn. , As the saying goes We don't produce code , Just a porter in the code world .

I've collected a lot of scripts before , Unified in their own code base

https://gitee.com/yashirochaos/yangchao

Not now python Our cloud computing engineers are not good networkers Come on, guys

版权声明
本文为[Leymus chinensis]所创,转载请带上原文链接,感谢
https://javamana.com/2021/05/20210530165826246n.html

  1. Netty源码解析-概述篇
  2. Netty源码解析-概述篇
  3. Netty源码解析1-Buffer
  4. Netty源码解析1-Buffer
  5. Netty源码解析2-Reactor
  6. Netty源码解析2-Reactor
  7. Netty源码解析3-Pipeline
  8. Netty源码解析3-Pipeline
  9. Netty源码解析4-Handler综述
  10. Netty源码解析4-Handler综述
  11. Netty源码解析5-ChannelHandler
  12. Netty源码解析5-ChannelHandler
  13. Netty源码解析6-ChannelHandler实例之LoggingHandler
  14. Netty源码解析6-ChannelHandler实例之LoggingHandler
  15. Netty源码解析7-ChannelHandler实例之TimeoutHandler
  16. Netty源码解析7-ChannelHandler实例之TimeoutHandler
  17. Netty源码解析8-ChannelHandler实例之CodecHandler
  18. Netty源码解析8-ChannelHandler实例之CodecHandler
  19. Netty源码解析9-ChannelHandler实例之MessageToByteEncoder
  20. Netty源码解析9-ChannelHandler实例之MessageToByteEncoder
  21. 大数据面试题之Hbase系列
  22. 你可能需要的Kafka面试题与答案整理
  23. 你可能需要的Kafka面试题与答案整理
  24. 后起之秀Pulsar VS. 传统强者Kafka?谁更强
  25. 后起之秀Pulsar VS. 传统强者Kafka?谁更强
  26. 【大数据哔哔集20210123】别问,问就是Kafka最可靠
  27. 【大数据哔哔集20210123】别问,问就是Kafka最可靠
  28. 【大数据哔哔集20210124】有人问我Kafka Leader选举?我真没慌
  29. 【大数据哔哔集20210124】有人问我Kafka Leader选举?我真没慌
  30. 【大数据哔哔集20210117】Kafka 的高可靠性是怎么实现的
  31. 【大数据哔哔集20210117】Kafka 的高可靠性是怎么实现的
  32. Kafka Connect | 无缝结合Kafka构建高效ETL方案
  33. Kafka面试题总结(一)
  34. Kafka面试题总结(一)
  35. Kafka面试题整理(二)
  36. Kafka面试题整理(二)
  37. 基于Kafka Flink Redis的电商大屏实时计算案例
  38. 基于Kafka Flink Redis的电商大屏实时计算案例
  39. Google布隆过滤器与Redis布隆过滤器详解
  40. Google布隆过滤器与Redis布隆过滤器详解
  41. 【Java Web前端开发】前端框架 bootstrap+jquery+angularjs探索
  42. 关于Redis的几件小事 | 高并发和高可用
  43. 关于Redis的几件小事 | 高并发和高可用
  44. 关于redis的几件小事(一)redis的使用目的与问题
  45. 关于redis的几件小事(一)redis的使用目的与问题
  46. 阿里云Redis技术架构演进
  47. 阿里云Redis技术架构演进
  48. 阿里云Redis技术架构演进
  49. Flink实战(109):connector(十八)hdfs 读写(三)StreamingFileSink相关特性及代码实战
  50. Flink实战(110):flink-sql使用(十八)connector(十九)Flink 与 hive 结合使用(七) Flink Hive Connector 使用
  51. Flink实战(110):flink-sql使用(十八)connector(十九)Flink 与 hive 结合使用(七) Flink Hive Connector 使用
  52. Flink实战(111):flink-sql使用(十九)Flink 与 hive 结合使用(八)Hive Streaming 实战解析
  53. Flink实战(111):flink-sql使用(十九)Flink 与 hive 结合使用(八)Hive Streaming 实战解析
  54. Docker常用命令,这些都要会!
  55. 鸟哥的Linux私房菜学习之第九章笔记
  56. Java NIO之Channel(通道)
  57. Java NIO之拥抱Path和Files
  58. Redis changed its open source license, and many projects were no longer open source
  59. JDK 11 has entered the candidate release stage, and the official version is planned to be released on September 25
  60. [* *] the latest version of windows 10 hides Linux?