summaryrefslogtreecommitdiff
path: root/cloudinit/net/network_state.py
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/net/network_state.py')
-rw-r--r--cloudinit/net/network_state.py66
1 files changed, 51 insertions, 15 deletions
diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py
index e8bf9e39..8018cfb9 100644
--- a/cloudinit/net/network_state.py
+++ b/cloudinit/net/network_state.py
@@ -237,6 +237,7 @@ class NetworkStateInterpreter(metaclass=CommandHandlerMeta):
self._network_state = copy.deepcopy(self.initial_network_state)
self._network_state['config'] = config
self._parsed = False
+ self._interface_dns_map = {}
@property
def network_state(self):
@@ -310,6 +311,21 @@ class NetworkStateInterpreter(metaclass=CommandHandlerMeta):
LOG.warning("Skipping invalid command: %s", command,
exc_info=True)
LOG.debug(self.dump_network_state())
+ for interface, dns in self._interface_dns_map.items():
+ iface = None
+ try:
+ iface = self._network_state['interfaces'][interface]
+ except KeyError as e:
+ raise ValueError(
+ 'Nameserver specified for interface {0}, '
+ 'but interface {0} does not exist!'.format(interface)
+ ) from e
+ if iface:
+ nameservers, search = dns
+ iface['dns'] = {
+ 'addresses': nameservers,
+ 'search': search,
+ }
def parse_config_v2(self, skip_broken=True):
for command_type, command in self._config.items():
@@ -526,21 +542,40 @@ class NetworkStateInterpreter(metaclass=CommandHandlerMeta):
def handle_infiniband(self, command):
self.handle_physical(command)
- @ensure_command_keys(['address'])
- def handle_nameserver(self, command):
- dns = self._network_state.get('dns')
+ def _parse_dns(self, command):
+ nameservers = []
+ search = []
if 'address' in command:
addrs = command['address']
if not type(addrs) == list:
addrs = [addrs]
for addr in addrs:
- dns['nameservers'].append(addr)
+ nameservers.append(addr)
if 'search' in command:
paths = command['search']
if not isinstance(paths, list):
paths = [paths]
for path in paths:
- dns['search'].append(path)
+ search.append(path)
+ return nameservers, search
+
+ @ensure_command_keys(['address'])
+ def handle_nameserver(self, command):
+ dns = self._network_state.get('dns')
+ nameservers, search = self._parse_dns(command)
+ if 'interface' in command:
+ self._interface_dns_map[command['interface']] = (
+ nameservers, search
+ )
+ else:
+ dns['nameservers'].extend(nameservers)
+ dns['search'].extend(search)
+
+ @ensure_command_keys(['address'])
+ def _handle_individual_nameserver(self, command, iface):
+ _iface = self._network_state.get('interfaces')
+ nameservers, search = self._parse_dns(command)
+ _iface[iface]['dns'] = {'nameservers': nameservers, 'search': search}
@ensure_command_keys(['destination'])
def handle_route(self, command):
@@ -706,16 +741,17 @@ class NetworkStateInterpreter(metaclass=CommandHandlerMeta):
def _v2_common(self, cfg):
LOG.debug('v2_common: handling config:\n%s', cfg)
- if 'nameservers' in cfg:
- search = cfg.get('nameservers').get('search', [])
- dns = cfg.get('nameservers').get('addresses', [])
- name_cmd = {'type': 'nameserver'}
- if len(search) > 0:
- name_cmd.update({'search': search})
- if len(dns) > 0:
- name_cmd.update({'addresses': dns})
- LOG.debug('v2(nameserver) -> v1(nameserver):\n%s', name_cmd)
- self.handle_nameserver(name_cmd)
+ for iface, dev_cfg in cfg.items():
+ if 'nameservers' in dev_cfg:
+ search = dev_cfg.get('nameservers').get('search', [])
+ dns = dev_cfg.get('nameservers').get('addresses', [])
+ name_cmd = {'type': 'nameserver'}
+ if len(search) > 0:
+ name_cmd.update({'search': search})
+ if len(dns) > 0:
+ name_cmd.update({'address': dns})
+ self.handle_nameserver(name_cmd)
+ self._handle_individual_nameserver(name_cmd, iface)
def _handle_bond_bridge(self, command, cmd_type=None):
"""Common handler for bond and bridge types"""