summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniil Baturin <daniil@baturin.org>2019-08-21 09:09:07 +0200
committerDaniil Baturin <daniil@baturin.org>2019-08-21 09:09:07 +0200
commit63855b5c6b674d102804b43bcda85499a43973a4 (patch)
treeb406be2744ad76f3698d5f63567534badd71f4b9
parenta923efc0062119189d876e37514bd24b7773509e (diff)
downloadvyos-1x-63855b5c6b674d102804b43bcda85499a43973a4.tar.gz
vyos-1x-63855b5c6b674d102804b43bcda85499a43973a4.zip
T1598: redo host_name.py to use vyos-hostsd.
-rwxr-xr-xsrc/conf_mode/host_name.py196
1 files changed, 36 insertions, 160 deletions
diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py
index 2fad57db6..bb1ec9597 100755
--- a/src/conf_mode/host_name.py
+++ b/src/conf_mode/host_name.py
@@ -30,57 +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 }} {{ hostname }}{% 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
-
-# static hostname mappings
-{%- if static_host_mapping['hostnames'] %}
-{% for hn in static_host_mapping['hostnames'] -%}
-{{static_host_mapping['hostnames'][hn]['ipaddr']}}\t{{static_host_mapping['hostnames'][hn]['alias']}}\t{{hn}}
-{% endfor -%}
-{%- endif %}
-
-### 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': '',
@@ -89,32 +44,10 @@ 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
-
if conf.exists("system host-name"):
hosts['hostname'] = conf.return_value("system host-name")
# This may happen if the config is not loaded yet,
@@ -136,19 +69,15 @@ def get_config(arguments):
hosts['no_dhcp_ns'] = conf.exists('system disable-dhcp-nameservers')
# system static-host-mapping
- hosts['static_host_mapping'] = {'hostnames': {}}
+ 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'):
- hosts['static_host_mapping']['hostnames'][hn] = {
- 'ipaddr': conf.return_value('system static-host-mapping host-name ' + hn + ' inet'),
- 'alias': ''
- }
-
- if conf.exists('system static-host-mapping host-name ' + hn + ' alias'):
- a = conf.return_values(
- 'system static-host-mapping host-name ' + hn + ' alias')
- hosts['static_host_mapping']['hostnames'][hn]['alias'] = " ".join(a)
+ 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
@@ -180,83 +109,43 @@ def verify(config):
'The search list is currently limited to 256 characters')
# static mappings alias hostname
- if config['static_host_mapping']['hostnames']:
- for hn in config['static_host_mapping']['hostnames']:
- if not config['static_host_mapping']['hostnames'][hn]['ipaddr']:
- raise ConfigError('IP address required for ' + hn)
- for hn_alias in config['static_host_mapping']['hostnames'][hn]['alias'].split(' '):
- if not hostname_regex.match(hn_alias) and len(hn_alias) != 0:
- raise ConfigError('Invalid hostname alias ' + hn_alias)
+ 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)
-
- if not config['no_dhcp_ns']:
- config['nameserver'] += dhcp_ns
- config['domain_search'] += dhcp_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))
-
- # We have third party scripts altering /etc/hosts, too.
- # One example are the DHCP hostname update scripts thus we need to cache in
- # every modification first - so changing domain-name, domain-search or hostname
- # during runtime works
- old_hosts = ""
- with open(config_file_hosts, 'r') as f:
- # Skips text before the beginning of our marker.
- # NOTE: Marker __MUST__ match the one specified in config_tmpl_hosts
- for line in f:
- if line.strip() == '### modifications from other scripts should be added below':
- break
-
- for line in f:
- # This additional line.strip() filters empty lines
- if line.strip():
- old_hosts += line
-
- # Add an additional newline
- old_hosts += '\n'
-
- tmpl = jinja2.Template(config_tmpl_hosts)
- config_text = tmpl.render(config)
-
- with open(config_file_hosts, 'w') as f:
- f.write(config_text)
- f.write(old_hosts)
-
- 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']
@@ -283,22 +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 it's called from dhclient, then either:
- # a) verification was already done at commit time
- # b) it's run on an unconfigured system, e.g. by cloud-init
- # Therefore, verification is either redundant or useless
- if not args.dhclient:
- verify(c)
+ c = get_config()
+ verify(c)
generate(c)
apply(c)
except ConfigError as e: