From 76b275f00ae6eba35195a3027fb8960bd872491f Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Thu, 29 Aug 2019 12:09:30 +0200 Subject: T1598: import the new host_name.py from current. --- src/conf_mode/host_name.py | 170 ++++++++++++++------------------------------- 1 file changed, 53 insertions(+), 117 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py index ccf8ea175..bb1ec9597 100755 --- a/src/conf_mode/host_name.py +++ b/src/conf_mode/host_name.py @@ -30,51 +30,12 @@ import argparse import jinja2 import vyos.util +import vyos.hostsd_client from vyos.config import Config from vyos import ConfigError -parser = argparse.ArgumentParser() -parser.add_argument("--dhclient", action="store_true", - help="Started from dhclient-script") - -config_file_hosts = '/etc/hosts' -config_file_resolv = '/etc/resolv.conf' - -config_tmpl_hosts = """ -### Autogenerated by host_name.py ### -127.0.0.1 localhost -127.0.1.1 {{ hostname }}{% if domain_name %}.{{ domain_name }}{% endif %} - -# The following lines are desirable for IPv6 capable hosts -::1 localhost ip6-localhost ip6-loopback -fe00::0 ip6-localnet -ff00::0 ip6-mcastprefix -ff02::1 ip6-allnodes -ff02::2 ip6-allrouters - -### modifications from other scripts should be added below - - -""" - -config_tmpl_resolv = """ -### Autogenerated by host_name.py ### -{% for ns in nameserver -%} -nameserver {{ ns }} -{% endfor -%} - -{%- if domain_name %} -domain {{ domain_name }} -{%- endif %} - -{%- if domain_search %} -search {{ domain_search | join(" ") }} -{%- endif %} - -""" - default_config_data = { 'hostname': 'vyos', 'domain_name': '', @@ -83,39 +44,19 @@ default_config_data = { 'no_dhcp_ns': False } - -# borrowed from: https://github.com/donjajo/py-world/blob/master/resolvconfReader.py, THX! -def get_resolvers(file): - resolv = {} - try: - with open(file, 'r') as resolvconf: - lines = [line.split('#', 1)[0].rstrip() - for line in resolvconf.readlines()] - resolvers = [line.split()[1] - for line in lines if 'nameserver' in line] - domains = [line.split()[1] for line in lines if 'search' in line] - resolv['resolvers'] = resolvers - resolv['domains'] = domains - return resolv - except IOError: - return [] - - -def get_config(arguments): +def get_config(): conf = Config() hosts = copy.deepcopy(default_config_data) - if arguments.dhclient: - conf.exists = conf.exists_effective - conf.return_value = conf.return_effective_value - conf.return_values = conf.return_effective_values - - hosts['hostname'] = conf.return_value("system host-name") - if not hosts['hostname']: - hosts['hostname'] = default_config_data['hostname'] - hosts['domain_name'] = conf.return_value("system domain-name") + if conf.exists("system host-name"): + hosts['hostname'] = conf.return_value("system host-name") + # This may happen if the config is not loaded yet, + # e.g. if run by cloud-init + if not hosts['hostname']: + hosts['hostname'] = default_config_data['hostname'] - if hosts['domain_name']: + if conf.exists("system domain-name"): + hosts['domain_name'] = conf.return_value("system domain-name") hosts['domain_search'].append(hosts['domain_name']) for search in conf.return_values("system domain-search domain"): @@ -124,7 +65,19 @@ def get_config(arguments): if conf.exists("system name-server"): hosts['nameserver'] = conf.return_values("system name-server") - hosts['no_dhcp_ns'] = conf.exists('system disable-dhcp-nameservers') + if conf.exists("system disable-dhcp-nameservers"): + hosts['no_dhcp_ns'] = conf.exists('system disable-dhcp-nameservers') + + # system static-host-mapping + hosts['static_host_mapping'] = [] + + if conf.exists('system static-host-mapping host-name'): + for hn in conf.list_nodes('system static-host-mapping host-name'): + mapping = {} + mapping['host'] = hn + mapping['address'] = conf.return_value('system static-host-mapping host-name {0} inet'.format(hn)) + mapping['aliases'] = conf.return_values('system static-host-mapping host-name {0} alias'.format(hn)) + hosts['static_host_mapping'].append(mapping) return hosts @@ -155,52 +108,44 @@ def verify(config): raise ConfigError( 'The search list is currently limited to 256 characters') + # static mappings alias hostname + if config['static_host_mapping']: + for m in config['static_host_mapping']: + if not m['address']: + raise ConfigError('IP address required for ' + m['host']) + for a in m['aliases']: + if not hostname_regex.match(a) and len(a) != 0: + raise ConfigError('Invalid alias \'{0}\' in mapping {1}'.format(a, m['host'])) + return None def generate(config): + pass + +def apply(config): if config is None: return None - # If "system disable-dhcp-nameservers" is __configured__ all DNS resolvers - # received via dhclient should not be added into the final 'resolv.conf'. - # - # We iterate over every resolver file and retrieve the received nameservers - # for later adjustment of the system nameservers - dhcp_ns = [] - dhcp_sd = [] - for file in glob.glob('/etc/resolv.conf.dhclient-new*'): - for key, value in get_resolvers(file).items(): - ns = [r for r in value if key == 'resolvers'] - dhcp_ns.extend(ns) - sd = [d for d in value if key == 'domains'] - dhcp_sd.extend(sd) - # Prune duplicate values - # Not order preserving, but then when multiple DHCP clients are used, - # there can't be guarantees about the order anyway - dhcp_ns = list(set(dhcp_ns)) - dhcp_sd = list(set(dhcp_sd)) - - if not config['no_dhcp_ns']: - config['nameserver'] += dhcp_ns - config['domain_search'] += dhcp_sd - - tmpl = jinja2.Template(config_tmpl_hosts) - config_text = tmpl.render(config) - with open(config_file_hosts, 'w') as f: - f.write(config_text) - - tmpl = jinja2.Template(config_tmpl_resolv) - config_text = tmpl.render(config) - with open(config_file_resolv, 'w') as f: - f.write(config_text) + ## Send the updated data to vyos-hostsd - return None + # vyos-hostsd uses "tags" to identify data sources + tag = "static" + try: + client = vyos.hostsd_client.Client() -def apply(config): - if config is None: - return None + client.set_host_name(config['hostname'], config['domain_name'], config['domain_search']) + + client.delete_name_servers(tag) + client.add_name_servers(tag, config['nameserver']) + + client.delete_hosts(tag) + client.add_hosts(tag, config['static_host_mapping']) + except vyos.hostsd_client.VyOSHostsdError as e: + raise ConfigError(str(e)) + + ## Actually update the hostname -- vyos-hostsd doesn't do that # No domain name -- the Debian way. hostname_new = config['hostname'] @@ -227,18 +172,9 @@ def apply(config): if __name__ == '__main__': - args = parser.parse_args() - - if args.dhclient: - # There's a big chance it was triggered by a commit still in progress - # so we need to wait until the new values are in the running config - vyos.util.wait_for_commit_lock() - - try: - c = get_config(args) - if not args.dhclient: - verify(c) + c = get_config() + verify(c) generate(c) apply(c) except ConfigError as e: -- cgit v1.2.3