summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--op-mode-definitions/clear-dhcp-server-lease.xml.in20
-rwxr-xr-xsrc/op_mode/clear_dhcp_lease.py73
2 files changed, 93 insertions, 0 deletions
diff --git a/op-mode-definitions/clear-dhcp-server-lease.xml.in b/op-mode-definitions/clear-dhcp-server-lease.xml.in
new file mode 100644
index 000000000..b1241588c
--- /dev/null
+++ b/op-mode-definitions/clear-dhcp-server-lease.xml.in
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="clear">
+ <children>
+ <node name="dhcp-server">
+ <properties>
+ <help>clear DHCP server lease</help>
+ </properties>
+ <children>
+ <tagNode name="lease">
+ <properties>
+ <help>DHCP server lease</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/clear_dhcp_lease.py --ip $4</command>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/src/op_mode/clear_dhcp_lease.py b/src/op_mode/clear_dhcp_lease.py
new file mode 100755
index 000000000..6ac3d4c1c
--- /dev/null
+++ b/src/op_mode/clear_dhcp_lease.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+
+import argparse
+import re
+
+from isc_dhcp_leases import Lease
+from isc_dhcp_leases import IscDhcpLeases
+
+from vyos.configquery import ConfigTreeQuery
+from vyos.util import ask_yes_no
+from vyos.util import call
+
+
+config = ConfigTreeQuery()
+base = ['service', 'dhcp-server']
+lease_file = '/config/dhcpd.leases'
+
+
+def del_lease_ip(address):
+ """
+ Read lease_file and write data to this file
+ without specific section "lease ip"
+ Delete section "lease x.x.x.x { x;x;x; }"
+ """
+ with open(lease_file, encoding='utf-8') as f:
+ data = f.read().rstrip()
+ lease_config_ip = '{(?P<config>[\s\S]+?)\n}'
+ pattern = rf"lease {address} {lease_config_ip}"
+ # Delete lease for ip block
+ data = re.sub(pattern, '', data)
+
+ # Write new data to original lease_file
+ with open(lease_file, 'w', encoding='utf-8') as f:
+ f.write(data)
+
+def is_ip_in_leases(address):
+ """
+ Return True if address found in the lease file
+ """
+ leases = IscDhcpLeases(lease_file)
+ lease_ips = []
+ for lease in leases.get():
+ lease_ips.append(lease.ip)
+ if address not in lease_ips:
+ print(f'Address "{address}" not found in "{lease_file}"')
+ return False
+ return True
+
+
+if not config.exists(base):
+ print('DHCP-server not configured!')
+ exit(0)
+
+if config.exists(base + ['failover']):
+ print('Lease cannot be reset in failover mode!')
+ exit(0)
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--ip', help='IPv4 address', action='store', required=True)
+
+ args = parser.parse_args()
+ address = args.ip
+
+ if not is_ip_in_leases(address):
+ exit(1)
+
+ if not ask_yes_no(f'This will restart DHCP server.\nContinue?'):
+ exit(1)
+ else:
+ del_lease_ip(address)
+ call('systemctl restart isc-dhcp-server.service')