diff options
| -rw-r--r-- | op-mode-definitions/clear-dhcp-server-lease.xml.in | 20 | ||||
| -rwxr-xr-x | src/op_mode/clear_dhcp_lease.py | 73 | 
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') | 
