write dns info to networkd
Write dns info to networkd so it can be consumed by resolved if resolved is enabled. Change-Id: Ia7b55e9a538cc6f060bc08da85123d7bb3a4f73e
This commit is contained in:
parent
9f629b8531
commit
84f6dd118a
55
glean/cmd.py
55
glean/cmd.py
@ -31,6 +31,16 @@ from glean import systemlock
|
|||||||
from glean import utils
|
from glean import utils
|
||||||
from glean._vendor import distro
|
from glean._vendor import distro
|
||||||
|
|
||||||
|
try:
|
||||||
|
import configparser
|
||||||
|
except ImportError:
|
||||||
|
import ConfigParser as configparser
|
||||||
|
|
||||||
|
try:
|
||||||
|
from StringIO import StringIO
|
||||||
|
except ImportError:
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
log = logging.getLogger("glean")
|
log = logging.getLogger("glean")
|
||||||
|
|
||||||
|
|
||||||
@ -312,7 +322,7 @@ def write_redhat_interfaces(interfaces, sys_interfaces, distro):
|
|||||||
return files_to_write
|
return files_to_write
|
||||||
|
|
||||||
|
|
||||||
def _write_networkd_interface(name, interfaces, files_struct=dict()):
|
def _write_networkd_interface(name, interfaces, args, files_struct=dict()):
|
||||||
vlans = []
|
vlans = []
|
||||||
for interface in interfaces:
|
for interface in interfaces:
|
||||||
iname = name
|
iname = name
|
||||||
@ -340,6 +350,15 @@ def _write_networkd_interface(name, interfaces, files_struct=dict()):
|
|||||||
('bond_mode' in interface)):
|
('bond_mode' in interface)):
|
||||||
if '[Network]' not in files_struct[network_file]:
|
if '[Network]' not in files_struct[network_file]:
|
||||||
files_struct[network_file]['[Network]'] = list()
|
files_struct[network_file]['[Network]'] = list()
|
||||||
|
if 'services' in interface:
|
||||||
|
for service in interface['services']:
|
||||||
|
if service['type'] == 'dns':
|
||||||
|
if not args.skip_dns:
|
||||||
|
files_struct[network_file]['[Network]'].append(
|
||||||
|
'DNS={address}'.format(
|
||||||
|
address=service['address']
|
||||||
|
)
|
||||||
|
)
|
||||||
# dhcp network, set to yes if both dhcp6 and dhcp4 are set
|
# dhcp network, set to yes if both dhcp6 and dhcp4 are set
|
||||||
if interface['type'] == 'ipv4_dhcp':
|
if interface['type'] == 'ipv4_dhcp':
|
||||||
if 'DHCP=ipv6' in files_struct[network_file]['[Network]']:
|
if 'DHCP=ipv6' in files_struct[network_file]['[Network]']:
|
||||||
@ -492,7 +511,7 @@ def _write_networkd_interface(name, interfaces, files_struct=dict()):
|
|||||||
return files_struct
|
return files_struct
|
||||||
|
|
||||||
|
|
||||||
def write_networkd_interfaces(interfaces, sys_interfaces):
|
def write_networkd_interfaces(interfaces, sys_interfaces, args):
|
||||||
files_to_write = dict()
|
files_to_write = dict()
|
||||||
gen_intfs = {}
|
gen_intfs = {}
|
||||||
files_struct = dict()
|
files_struct = dict()
|
||||||
@ -531,7 +550,7 @@ def write_networkd_interfaces(interfaces, sys_interfaces):
|
|||||||
intf.get('link', intf['id']) for intf in interfs
|
intf.get('link', intf['id']) for intf in interfs
|
||||||
if 'bond_mode' in intf)
|
if 'bond_mode' in intf)
|
||||||
files_struct = _write_networkd_interface(
|
files_struct = _write_networkd_interface(
|
||||||
interface_name, interfs, files_struct)
|
interface_name, interfs, args, files_struct)
|
||||||
|
|
||||||
for mac, iname in sorted(
|
for mac, iname in sorted(
|
||||||
sys_interfaces.items(), key=lambda x: x[1]):
|
sys_interfaces.items(), key=lambda x: x[1]):
|
||||||
@ -545,7 +564,7 @@ def write_networkd_interfaces(interfaces, sys_interfaces):
|
|||||||
continue
|
continue
|
||||||
interface = {'type': 'ipv4_dhcp', 'mac_address': mac}
|
interface = {'type': 'ipv4_dhcp', 'mac_address': mac}
|
||||||
files_struct = _write_networkd_interface(
|
files_struct = _write_networkd_interface(
|
||||||
iname, [interface], files_struct)
|
iname, [interface], args, files_struct)
|
||||||
|
|
||||||
for networkd_file in files_struct:
|
for networkd_file in files_struct:
|
||||||
file_contents = '# Automatically generated, do not edit\n'
|
file_contents = '# Automatically generated, do not edit\n'
|
||||||
@ -912,10 +931,30 @@ def write_debian_interfaces(interfaces, sys_interfaces):
|
|||||||
|
|
||||||
|
|
||||||
def write_dns_info(dns_servers):
|
def write_dns_info(dns_servers):
|
||||||
results = ""
|
resolve_confs = {}
|
||||||
|
resolv_nameservers = ""
|
||||||
for server in dns_servers:
|
for server in dns_servers:
|
||||||
results += "nameserver {0}\n".format(server)
|
resolv_nameservers += "nameserver {0}\n".format(server)
|
||||||
return {'/etc/resolv.conf': results}
|
resolve_confs['/etc/resolv.conf'] = resolv_nameservers
|
||||||
|
# set up resolved if available
|
||||||
|
if os.path.isfile('/etc/systemd/resolved.conf'):
|
||||||
|
# read the existing config so we only overwrite what's needed
|
||||||
|
resolved_conf = configparser.ConfigParser()
|
||||||
|
resolved_conf.read('/etc/systemd/resolved.conf')
|
||||||
|
# create config section if not created
|
||||||
|
if not resolved_conf.has_section('Resolve'):
|
||||||
|
resolved_conf.add_section('Resolve')
|
||||||
|
# write space separated dns servers
|
||||||
|
resolved_conf.set('Resolve', 'DNS', " ".join(dns_servers))
|
||||||
|
# use stringio to output the resulting config to string
|
||||||
|
# configparser only outputs to file descriptors
|
||||||
|
resolved_conf_fd = StringIO("")
|
||||||
|
resolved_conf.write(resolved_conf_fd)
|
||||||
|
resolved_conf_output = resolved_conf_fd.getvalue()
|
||||||
|
resolved_conf_fd.close()
|
||||||
|
# add the config to files to be written
|
||||||
|
resolve_confs['/etc/systemd/resolved.conf'] = resolved_conf_output
|
||||||
|
return resolve_confs
|
||||||
|
|
||||||
|
|
||||||
def get_config_drive_interfaces(net):
|
def get_config_drive_interfaces(net):
|
||||||
@ -1012,7 +1051,7 @@ def write_static_network_info(
|
|||||||
)
|
)
|
||||||
elif args.distro in 'networkd':
|
elif args.distro in 'networkd':
|
||||||
files_to_write.update(
|
files_to_write.update(
|
||||||
write_networkd_interfaces(interfaces, sys_interfaces)
|
write_networkd_interfaces(interfaces, sys_interfaces, args)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
@ -43,7 +43,17 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ip_address": "2001:4802:7807:103:be76:4eff:fe20:d72f",
|
"ip_address": "2001:4802:7807:103:be76:4eff:fe20:d72f",
|
||||||
"id": "network1"
|
"id": "network1",
|
||||||
|
"services": [
|
||||||
|
{
|
||||||
|
"address": "1111:2222:3333:4444::1234",
|
||||||
|
"type": "dns"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "1.2.3.4",
|
||||||
|
"type": "dns"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"network_id": "11111111-1111-1111-1111-111111111111",
|
"network_id": "11111111-1111-1111-1111-111111111111",
|
||||||
|
52
glean/tests/fixtures/test/rax-iad.networkd.network.out.dns
vendored
Normal file
52
glean/tests/fixtures/test/rax-iad.networkd.network.out.dns
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
### Write /etc/resolv.conf
|
||||||
|
nameserver 69.20.0.196
|
||||||
|
nameserver 69.20.0.164
|
||||||
|
### Write /etc/systemd/network/eth0.network
|
||||||
|
# Automatically generated, do not edit
|
||||||
|
[Match]
|
||||||
|
MACAddress=bc:76:4e:20:d7:2f
|
||||||
|
Name=eth0
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
DNS=1.2.3.4
|
||||||
|
DNS=1111:2222:3333:4444::1234
|
||||||
|
IPv6AcceptRA=no
|
||||||
|
|
||||||
|
[Address]
|
||||||
|
Address=146.20.110.113/24
|
||||||
|
|
||||||
|
[Address]
|
||||||
|
Address=2001:4802:7807:103:be76:4eff:fe20:d72f/64
|
||||||
|
|
||||||
|
[Route]
|
||||||
|
Destination=0.0.0.0/0
|
||||||
|
Gateway=146.20.110.1
|
||||||
|
|
||||||
|
[Route]
|
||||||
|
Destination=::/0
|
||||||
|
Gateway=fe80::def
|
||||||
|
|
||||||
|
[Route]
|
||||||
|
Destination=fd30::/48
|
||||||
|
Gateway=fe80::f001
|
||||||
|
|
||||||
|
### Write /etc/systemd/network/eth1.network
|
||||||
|
# Automatically generated, do not edit
|
||||||
|
[Match]
|
||||||
|
MACAddress=bc:76:4e:20:d7:33
|
||||||
|
Name=eth1
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
IPv6AcceptRA=no
|
||||||
|
|
||||||
|
[Address]
|
||||||
|
Address=10.210.32.174/19
|
||||||
|
|
||||||
|
[Route]
|
||||||
|
Destination=10.176.0.0/12
|
||||||
|
Gateway=10.210.32.1
|
||||||
|
|
||||||
|
[Route]
|
||||||
|
Destination=10.208.0.0/12
|
||||||
|
Gateway=10.210.32.1
|
||||||
|
|
@ -85,7 +85,7 @@ class TestGlean(base.BaseTestCase):
|
|||||||
'/etc/conf.d', '/etc/init.d', '/etc/sysconfig/network',
|
'/etc/conf.d', '/etc/init.d', '/etc/sysconfig/network',
|
||||||
'/etc/systemd/network')
|
'/etc/systemd/network')
|
||||||
mock_files = ('/etc/resolv.conf', '/etc/hostname', '/etc/hosts',
|
mock_files = ('/etc/resolv.conf', '/etc/hostname', '/etc/hosts',
|
||||||
'/bin/systemctl')
|
'/etc/systemd/resolved.conf', '/bin/systemctl')
|
||||||
if (path.startswith(mock_dirs) or path in mock_files):
|
if (path.startswith(mock_dirs) or path in mock_files):
|
||||||
try:
|
try:
|
||||||
mock_handle = self.file_handle_mocks[path]
|
mock_handle = self.file_handle_mocks[path]
|
||||||
@ -193,6 +193,9 @@ class TestGlean(base.BaseTestCase):
|
|||||||
|
|
||||||
output_filename = '%s.%s.network.out' % (provider, distro.lower())
|
output_filename = '%s.%s.network.out' % (provider, distro.lower())
|
||||||
output_path = os.path.join(sample_data_path, 'test', output_filename)
|
output_path = os.path.join(sample_data_path, 'test', output_filename)
|
||||||
|
if not skip_dns:
|
||||||
|
if os.path.exists(output_path + '.dns'):
|
||||||
|
output_path = output_path + '.dns'
|
||||||
|
|
||||||
# Generate a list of (dest, content) into write_blocks to assert
|
# Generate a list of (dest, content) into write_blocks to assert
|
||||||
write_blocks = []
|
write_blocks = []
|
||||||
@ -260,7 +263,8 @@ class TestGlean(base.BaseTestCase):
|
|||||||
# comes up with "--interface". This simulates that.
|
# comes up with "--interface". This simulates that.
|
||||||
def test_glean_systemd(self):
|
def test_glean_systemd(self):
|
||||||
with mock.patch('glean.systemlock.Lock'):
|
with mock.patch('glean.systemlock.Lock'):
|
||||||
self._assert_distro_provider(self.distro, self.style, 'eth0')
|
self._assert_distro_provider(self.distro, self.style,
|
||||||
|
'eth0', skip_dns=True)
|
||||||
|
|
||||||
def test_glean_skip_dns(self):
|
def test_glean_skip_dns(self):
|
||||||
with mock.patch('glean.systemlock.Lock'):
|
with mock.patch('glean.systemlock.Lock'):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user