Merge "Fix extra-dhcp-opt on stateless dhcpv6 subnet" into stable/juno
This commit is contained in:
commit
de6b3806c6
|
@ -469,6 +469,8 @@ class Dnsmasq(DhcpLocalProcess):
|
|||
(
|
||||
port, # a DictModel instance representing the port.
|
||||
alloc, # a DictModel instance of the allocated ip and subnet.
|
||||
# if alloc is None, it means there is no need to allocate
|
||||
# an IPv6 address because of stateless DHCPv6 network.
|
||||
host_name, # Host name.
|
||||
name, # Canonical hostname in the format 'hostname[.domain]'.
|
||||
)
|
||||
|
@ -482,8 +484,13 @@ class Dnsmasq(DhcpLocalProcess):
|
|||
# dhcp agent
|
||||
if alloc.subnet_id in v6_nets:
|
||||
addr_mode = v6_nets[alloc.subnet_id].ipv6_address_mode
|
||||
if addr_mode != constants.DHCPV6_STATEFUL:
|
||||
if addr_mode == constants.IPV6_SLAAC:
|
||||
continue
|
||||
elif addr_mode == constants.DHCPV6_STATELESS:
|
||||
alloc = hostname = fqdn = None
|
||||
yield (port, alloc, hostname, fqdn)
|
||||
continue
|
||||
|
||||
hostname = 'host-%s' % alloc.ip_address.replace(
|
||||
'.', '-').replace(':', '-')
|
||||
fqdn = hostname
|
||||
|
@ -512,6 +519,14 @@ class Dnsmasq(DhcpLocalProcess):
|
|||
|
||||
LOG.debug(_('Building host file: %s'), filename)
|
||||
for (port, alloc, hostname, name) in self._iter_hosts():
|
||||
if not alloc:
|
||||
if getattr(port, 'extra_dhcp_opts', False):
|
||||
buf.write('%s,%s%s\n' %
|
||||
(port.mac_address, 'set:', port.id))
|
||||
LOG.debug('Adding %(mac)s : set:%(tag)s',
|
||||
{"mac": port.mac_address, "tag": port.id})
|
||||
continue
|
||||
|
||||
# (dzyu) Check if it is legal ipv6 address, if so, need wrap
|
||||
# it with '[]' to let dnsmasq to distinguish MAC address from
|
||||
# IPv6 address.
|
||||
|
@ -519,17 +534,20 @@ class Dnsmasq(DhcpLocalProcess):
|
|||
if netaddr.valid_ipv6(ip_address):
|
||||
ip_address = '[%s]' % ip_address
|
||||
|
||||
LOG.debug(_('Adding %(mac)s : %(name)s : %(ip)s'),
|
||||
{"mac": port.mac_address, "name": name,
|
||||
"ip": ip_address})
|
||||
|
||||
if getattr(port, 'extra_dhcp_opts', False):
|
||||
buf.write('%s,%s,%s,%s%s\n' %
|
||||
(port.mac_address, name, ip_address,
|
||||
'set:', port.id))
|
||||
LOG.debug('Adding %(mac)s : %(name)s : %(ip)s : '
|
||||
'set:%(tag)s',
|
||||
{"mac": port.mac_address, "name": name,
|
||||
"ip": ip_address, "tag": port.id})
|
||||
else:
|
||||
buf.write('%s,%s,%s\n' %
|
||||
(port.mac_address, name, ip_address))
|
||||
LOG.debug('Adding %(mac)s : %(name)s : %(ip)s',
|
||||
{"mac": port.mac_address, "name": name,
|
||||
"ip": ip_address})
|
||||
|
||||
utils.replace_file(filename, buf.getvalue())
|
||||
LOG.debug(_('Done building host file %s'), filename)
|
||||
|
@ -570,7 +588,8 @@ class Dnsmasq(DhcpLocalProcess):
|
|||
for (port, alloc, hostname, fqdn) in self._iter_hosts():
|
||||
# It is compulsory to write the `fqdn` before the `hostname` in
|
||||
# order to obtain it in PTR responses.
|
||||
buf.write('%s\t%s %s\n' % (alloc.ip_address, fqdn, hostname))
|
||||
if alloc:
|
||||
buf.write('%s\t%s %s\n' % (alloc.ip_address, fqdn, hostname))
|
||||
addn_hosts = self.get_conf_file_name('addn_hosts')
|
||||
utils.replace_file(addn_hosts, buf.getvalue())
|
||||
return addn_hosts
|
||||
|
|
|
@ -108,6 +108,21 @@ class FakeV6Port:
|
|||
self.extra_dhcp_opts = []
|
||||
|
||||
|
||||
class FakeV6PortExtraOpt(object):
|
||||
id = 'hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh'
|
||||
admin_state_up = True
|
||||
device_owner = 'foo3'
|
||||
fixed_ips = [FakeIPAllocation('ffea:3ba5:a17a:4ba3:0216:3eff:fec2:771d',
|
||||
'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee')]
|
||||
mac_address = '00:16:3e:c2:77:1d'
|
||||
|
||||
def __init__(self):
|
||||
self.extra_dhcp_opts = [
|
||||
DhcpOpt(opt_name='dns-server',
|
||||
opt_value='ffea:3ba5:a17a:4ba3::100',
|
||||
ip_version=6)]
|
||||
|
||||
|
||||
class FakeDualPort:
|
||||
id = 'hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh'
|
||||
admin_state_up = True
|
||||
|
@ -286,6 +301,18 @@ class FakeV6SubnetSlaac:
|
|||
ipv6_ra_mode = None
|
||||
|
||||
|
||||
class FakeV6SubnetStateless(object):
|
||||
id = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
|
||||
ip_version = 6
|
||||
cidr = 'ffea:3ba5:a17a:4ba3::/64'
|
||||
gateway_ip = 'ffea:3ba5:a17a:4ba3::1'
|
||||
enable_dhcp = True
|
||||
dns_nameservers = []
|
||||
host_routes = []
|
||||
ipv6_address_mode = constants.DHCPV6_STATELESS
|
||||
ipv6_ra_mode = None
|
||||
|
||||
|
||||
class FakeV4SubnetNoGateway:
|
||||
id = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
|
||||
ip_version = 4
|
||||
|
@ -470,6 +497,14 @@ class FakeDualStackNetworkSingleDHCP:
|
|||
ports = [FakePort1(), FakePort4(), FakeRouterPort()]
|
||||
|
||||
|
||||
class FakeV6NetworkStatelessDHCP(object):
|
||||
id = 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'
|
||||
|
||||
subnets = [FakeV6SubnetStateless()]
|
||||
ports = [FakeV6PortExtraOpt()]
|
||||
namespace = 'qdhcp-ns'
|
||||
|
||||
|
||||
class LocalChild(dhcp.DhcpLocalProcess):
|
||||
PORTS = {4: [4], 6: [6]}
|
||||
|
||||
|
@ -1406,6 +1441,21 @@ tag:tag0,option:router""".lstrip()
|
|||
self.safe.assert_has_calls([mock.call(exp_host_name,
|
||||
exp_host_data)])
|
||||
|
||||
def test_host_and_opts_file_on_stateless_dhcpv6_network(self):
|
||||
exp_host_name = '/dhcp/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb/host'
|
||||
exp_host_data = ('00:16:3e:c2:77:1d,'
|
||||
'set:hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh\n').lstrip()
|
||||
exp_opt_name = '/dhcp/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb/opts'
|
||||
exp_opt_data = ('tag:tag0,option6:domain-search,openstacklocal\n'
|
||||
'tag:hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,'
|
||||
'option6:dns-server,ffea:3ba5:a17a:4ba3::100').lstrip()
|
||||
dm = dhcp.Dnsmasq(self.conf, FakeV6NetworkStatelessDHCP(),
|
||||
version=dhcp.Dnsmasq.MINIMUM_VERSION)
|
||||
dm._output_hosts_file()
|
||||
dm._output_opts_file()
|
||||
self.safe.assert_has_calls([mock.call(exp_host_name, exp_host_data),
|
||||
mock.call(exp_opt_name, exp_opt_data)])
|
||||
|
||||
def test_should_enable_metadata_namespaces_disabled_returns_false(self):
|
||||
self.conf.set_override('use_namespaces', False)
|
||||
self.assertFalse(dhcp.Dnsmasq.should_enable_metadata(self.conf,
|
||||
|
|
Loading…
Reference in New Issue