From b6dcb0a887a4fab89ca870d6142d6856cccc181f Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Mon, 3 Aug 2020 13:51:48 +0200 Subject: ifconfig: T2653: unify DHCPv4 configuration Pass the interface dictionary transparently to the DHCP module and render the DHCP client config template directly from the same source instead of transcoding it once more. --- data/templates/dhcp-client/daemon-options.tmpl | 2 +- data/templates/dhcp-client/ipv4.tmpl | 20 +++++------ python/vyos/ifconfig/dhcp.py | 48 +++++++++++++------------- python/vyos/ifconfig/interface.py | 10 +----- 4 files changed, 36 insertions(+), 44 deletions(-) diff --git a/data/templates/dhcp-client/daemon-options.tmpl b/data/templates/dhcp-client/daemon-options.tmpl index 12786b777..a0ba2c9ef 100644 --- a/data/templates/dhcp-client/daemon-options.tmpl +++ b/data/templates/dhcp-client/daemon-options.tmpl @@ -1 +1 @@ -DHCLIENT_OPTS="-nw -cf {{ conf_file }} -pf {{ pid_file }} -lf {{ lease_file }} {{ '-S' if dhcpv6_prm_only }} {{ '-T' if dhcpv6_temporary }} {{ ifname }}" +DHCLIENT_OPTS="-nw -cf /var/lib/dhcp/dhclient_{{ifname}}.conf -pf /var/lib/dhcp/dhclient_{{ifname}}.pid -lf /var/lib/dhcp/dhclient_{{ifname}}.leases {{ifname}}" diff --git a/data/templates/dhcp-client/ipv4.tmpl b/data/templates/dhcp-client/ipv4.tmpl index ab772b5f6..fe2a67f08 100644 --- a/data/templates/dhcp-client/ipv4.tmpl +++ b/data/templates/dhcp-client/ipv4.tmpl @@ -4,14 +4,14 @@ timeout 60; retry 300; interface "{{ ifname }}" { - send host-name "{{ hostname }}"; - {% if client_id -%} - send dhcp-client-identifier "{{ client_id }}"; - {% endif -%} - {% if vendor_class_id -%} - send vendor-class-identifier "{{ vendor_class_id }}"; - {% endif -%} - request subnet-mask, broadcast-address, routers, domain-name-servers, - rfc3442-classless-static-routes, domain-name, interface-mtu; - require subnet-mask; + send host-name "{{ dhcp_options.host_name }}"; +{% if dhcp_options.client_id is defined and dhcp_options.client_id is not none %} + send dhcp-client-identifier "{{ dhcp_options.client_id }}"; +{% endif %} +{% if dhcp_options.vendor_class_id is defined and dhcp_options.vendor_class_id is not none %} + send vendor-class-identifier "{{ dhcp_options.vendor_class_id }}"; +{% endif %} + request subnet-mask, broadcast-address, routers, domain-name-servers, + rfc3442-classless-static-routes, domain-name, interface-mtu; + require subnet-mask; } diff --git a/python/vyos/ifconfig/dhcp.py b/python/vyos/ifconfig/dhcp.py index bd37970a2..5f99a0b7e 100644 --- a/python/vyos/ifconfig/dhcp.py +++ b/python/vyos/ifconfig/dhcp.py @@ -14,26 +14,22 @@ # License along with this library. If not, see . import os +import jmespath +from vyos.configdict import dict_merge from vyos.configverify import verify_dhcpv6 -from vyos.dicts import FixedDict from vyos.ifconfig.control import Control from vyos.template import render class _DHCPv4 (Control): def __init__(self, ifname): super().__init__() - config_base = r'/var/lib/dhcp/dhclient_' - self.options = FixedDict(**{ - 'ifname': ifname, - 'hostname': '', - 'client_id': '', - 'vendor_class_id': '', - 'conf_file': config_base + f'{ifname}.conf', - 'options_file': config_base + f'{ifname}.options', - 'pid_file': config_base + f'{ifname}.pid', - 'lease_file': config_base + f'{ifname}.leases', - }) + config_base = r'/var/lib/dhcp/dhclient' + self._conf_file = f'{config_base}_{ifname}.conf' + self._options_file = f'{config_base}_{ifname}.options' + self._pid_file = f'{config_base}_{ifname}.pid' + self._lease_file = f'{config_base}_{ifname}.leases' + self.options = {'ifname' : ifname} # replace dhcpv4/v6 with systemd.networkd? def set(self): @@ -42,19 +38,24 @@ class _DHCPv4 (Control): started in background! Example: - >>> from vyos.ifconfig import Interface >>> j = Interface('eth0') >>> j.dhcp.v4.set() """ - if not self.options['hostname']: + + if jmespath.search('dhcp_options.host_name', self.options) == None: # read configured system hostname. # maybe change to vyos hostd client ??? + hostname = 'vyos' with open('/etc/hostname', 'r') as f: - self.options['hostname'] = f.read().rstrip('\n') + hostname = f.read().rstrip('\n') + tmp = {'dhcp_options' : { 'host_name' : hostname}} + self.options = dict_merge(tmp, self.options) - render(self.options['options_file'], 'dhcp-client/daemon-options.tmpl', self.options) - render(self.options['conf_file'], 'dhcp-client/ipv4.tmpl', self.options) + render(self._options_file, 'dhcp-client/daemon-options.tmpl', + self.options, trim_blocks=True) + render(self._conf_file, 'dhcp-client/ipv4.tmpl', + self.options, trim_blocks=True) return self._cmd('systemctl restart dhclient@{ifname}.service'.format(**self.options)) @@ -64,21 +65,20 @@ class _DHCPv4 (Control): pid, config and lease will be removed. Example: - >>> from vyos.ifconfig import Interface >>> j = Interface('eth0') >>> j.dhcp.v4.delete() """ - if not os.path.isfile(self.options['pid_file']): + if not os.path.isfile(self._pid_file): self._debug_msg('No DHCP client PID found') return None self._cmd('systemctl stop dhclient@{ifname}.service'.format(**self.options)) # cleanup old config files - for name in ('conf_file', 'options_file', 'pid_file', 'lease_file'): - if os.path.isfile(self.options[name]): - os.remove(self.options[name]) + for file in [self._conf_file, self._options_file, self._pid_file, self._lease_file]: + if os.path.isfile(file): + os.remove(file) class _DHCPv6 (Control): def __init__(self, ifname): @@ -101,7 +101,8 @@ class _DHCPv6 (Control): # missed it we are safe! verify_dhcpv6(self.options) - render(self._config, 'dhcp-client/ipv6.tmpl', self.options, trim_blocks=True) + render(self._config, 'dhcp-client/ipv6.tmpl', + self.options, trim_blocks=True) return self._cmd('systemctl restart dhcp6c@{ifname}.service'.format( **self.options)) @@ -111,7 +112,6 @@ class _DHCPv6 (Control): pid, config and lease will be removed. Example: - >>> from vyos.ifconfig import Interface >>> j = Interface('eth0') >>> j.dhcp.v6.delete() diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index f5e43e172..214ece8cd 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -824,15 +824,7 @@ class Interface(Control): # DHCP options if 'dhcp_options' in config: - dhcp_options = config.get('dhcp_options') - if 'client_id' in dhcp_options: - self.dhcp.v4.options['client_id'] = dhcp_options.get('client_id') - - if 'host_name' in dhcp_options: - self.dhcp.v4.options['hostname'] = dhcp_options.get('host_name') - - if 'vendor_class_id' in dhcp_options: - self.dhcp.v4.options['vendor_class_id'] = dhcp_options.get('vendor_class_id') + self.dhcp.v4.options = config # DHCPv6 options if 'dhcpv6_options' in config: -- cgit v1.2.3