diff --git a/neutron/agent/linux/dhcp.py b/neutron/agent/linux/dhcp.py index a53b34ae3c1..9ab3ff8ae4b 100644 --- a/neutron/agent/linux/dhcp.py +++ b/neutron/agent/linux/dhcp.py @@ -312,7 +312,8 @@ class Dnsmasq(DhcpLocalProcess): [(UDP, DNS_PORT), (TCP, DNS_PORT), (UDP, DHCPV6_PORT)], } - _TAG_PREFIX = 'tag%d' + _SUBNET_TAG_PREFIX = 'subnet-%s' + _PORT_TAG_PREFIX = 'port-%s' _ID = 'id:' @@ -360,7 +361,7 @@ class Dnsmasq(DhcpLocalProcess): ] possible_leases = 0 - for i, subnet in enumerate(self._get_all_subnets(self.network)): + for subnet in self._get_all_subnets(self.network): mode = None # if a subnet is specified to have dhcp disabled if not subnet.enable_dhcp: @@ -388,7 +389,7 @@ class Dnsmasq(DhcpLocalProcess): if mode: if subnet.ip_version == 4: cmd.append('--dhcp-range=%s%s,%s,%s,%s,%s' % - ('set:', self._TAG_PREFIX % i, + ('set:', self._SUBNET_TAG_PREFIX % subnet.id, cidr.network, mode, cidr.netmask, lease)) else: if cidr.prefixlen < 64: @@ -397,7 +398,7 @@ class Dnsmasq(DhcpLocalProcess): {'subnet': subnet.id, 'cidr': cidr}) continue cmd.append('--dhcp-range=%s%s,%s,%s,%d,%s' % - ('set:', self._TAG_PREFIX % i, + ('set:', self._SUBNET_TAG_PREFIX % subnet.id, cidr.network, mode, cidr.prefixlen, lease)) possible_leases += cidr.size @@ -705,8 +706,9 @@ class Dnsmasq(DhcpLocalProcess): port, alloc, hostname, name, no_dhcp, no_opts = host_tuple if no_dhcp: if not no_opts and self._get_port_extra_dhcp_opts(port): - buf.write('%s,%s%s\n' % - (port.mac_address, 'set:', port.id)) + buf.write('%s,%s%s\n' % ( + port.mac_address, + 'set:', self._PORT_TAG_PREFIX % port.id)) continue # don't write ip address which belongs to a dhcp disabled subnet. @@ -720,7 +722,8 @@ class Dnsmasq(DhcpLocalProcess): if client_id and len(port.extra_dhcp_opts) > 1: buf.write('%s,%s%s,%s,%s,%s%s\n' % (port.mac_address, self._ID, client_id, name, - ip_address, 'set:', port.id)) + ip_address, 'set:', + self._PORT_TAG_PREFIX % port.id)) elif client_id and len(port.extra_dhcp_opts) == 1: buf.write('%s,%s%s,%s,%s\n' % (port.mac_address, self._ID, client_id, name, @@ -728,7 +731,7 @@ class Dnsmasq(DhcpLocalProcess): else: buf.write('%s,%s,%s,%s%s\n' % (port.mac_address, name, ip_address, - 'set:', port.id)) + 'set:', self._PORT_TAG_PREFIX % port.id)) else: buf.write('%s,%s,%s\n' % (port.mac_address, name, ip_address)) @@ -947,11 +950,11 @@ class Dnsmasq(DhcpLocalProcess): def _generate_opts_per_subnet(self): options = [] - subnet_index_map = {} + subnets_without_nameservers = set() if self.conf.enable_isolated_metadata or self.conf.force_metadata: subnet_to_interface_ip = self._make_subnet_interface_ip_map() isolated_subnets = self.get_isolated_subnets(self.network) - for i, subnet in enumerate(self._get_all_subnets(self.network)): + for subnet in self._get_all_subnets(self.network): addr_mode = getattr(subnet, 'ipv6_address_mode', None) segment_id = getattr(subnet, 'segment_id', None) if (not subnet.enable_dhcp or @@ -966,23 +969,30 @@ class Dnsmasq(DhcpLocalProcess): # Special case: Do not announce DNS servers options.append( self._format_option( - subnet.ip_version, i, 'dns-server')) + subnet.ip_version, + self._SUBNET_TAG_PREFIX % subnet.id, + 'dns-server')) else: options.append( self._format_option( - subnet.ip_version, i, 'dns-server', - ','.join( + subnet.ip_version, + self._SUBNET_TAG_PREFIX % subnet.id, + 'dns-server', ','.join( Dnsmasq._convert_to_literal_addrs( subnet.ip_version, subnet.dns_nameservers)))) else: # use the dnsmasq ip as nameservers only if there is no # dns-server submitted by the server - subnet_index_map[subnet.id] = i + # Here is something to check still + subnets_without_nameservers.add(subnet.id) if self.conf.dns_domain and subnet.ip_version == 6: - options.append('tag:tag%s,option6:domain-search,%s' % - (i, ''.join(self.conf.dns_domain))) + # This should be change also + options.append( + self._format_option( + subnet.ip_version, self._SUBNET_TAG_PREFIX % subnet.id, + "domain-search", ''.join(self.conf.dns_domain))) gateway = subnet.gateway_ip host_routes = [] @@ -1022,24 +1032,29 @@ class Dnsmasq(DhcpLocalProcess): host_routes.append("%s,%s" % (constants.IPv4_ANY, gateway)) options.append( - self._format_option(subnet.ip_version, i, - 'classless-static-route', - ','.join(host_routes))) + self._format_option( + subnet.ip_version, + self._SUBNET_TAG_PREFIX % subnet.id, + 'classless-static-route', + ','.join(host_routes))) options.append( - self._format_option(subnet.ip_version, i, - WIN2k3_STATIC_DNS, - ','.join(host_routes))) + self._format_option( + subnet.ip_version, + self._SUBNET_TAG_PREFIX % subnet.id, + WIN2k3_STATIC_DNS, + ','.join(host_routes))) if gateway: - options.append(self._format_option(subnet.ip_version, - i, 'router', - gateway)) + options.append(self._format_option( + subnet.ip_version, self._SUBNET_TAG_PREFIX % subnet.id, + 'router', gateway)) else: - options.append(self._format_option(subnet.ip_version, - i, 'router')) - return options, subnet_index_map + options.append(self._format_option( + subnet.ip_version, self._SUBNET_TAG_PREFIX % subnet.id, + 'router')) + return options, subnets_without_nameservers - def _generate_opts_per_port(self, subnet_index_map): + def _generate_opts_per_port(self, subnets_without_nameservers): options = [] dhcp_ips = collections.defaultdict(list) for port in self.network.ports: @@ -1055,8 +1070,10 @@ class Dnsmasq(DhcpLocalProcess): opt_ip_version = opt.ip_version if opt_ip_version in port_ip_versions: options.append( - self._format_option(opt_ip_version, port.id, - opt.opt_name, opt.opt_value)) + self._format_option( + opt_ip_version, + self._PORT_TAG_PREFIX % port.id, + opt.opt_name, opt.opt_value)) else: LOG.info("Cannot apply dhcp option %(opt)s " "because it's ip_version %(version)d " @@ -1069,19 +1086,19 @@ class Dnsmasq(DhcpLocalProcess): # by the server if port.device_owner == constants.DEVICE_OWNER_DHCP: for ip in port.fixed_ips: - i = subnet_index_map.get(ip.subnet_id) - if i is None: + if ip.subnet_id not in subnets_without_nameservers: continue - dhcp_ips[i].append(ip.ip_address) + dhcp_ips[ip.subnet_id].append(ip.ip_address) - for i, ips in dhcp_ips.items(): + for subnet_id, ips in dhcp_ips.items(): for ip_version in (4, 6): vx_ips = [ip for ip in ips if netaddr.IPAddress(ip).version == ip_version] if len(vx_ips) > 1: options.append( self._format_option( - ip_version, i, 'dns-server', + ip_version, self._SUBNET_TAG_PREFIX % subnet_id, + 'dns-server', ','.join( Dnsmasq._convert_to_literal_addrs(ip_version, vx_ips)))) @@ -1112,9 +1129,6 @@ class Dnsmasq(DhcpLocalProcess): extra_tag = matches.groups()[0] option = matches.groups()[2] - if isinstance(tag, int): - tag = self._TAG_PREFIX % tag - # NOTE(TheJulia): prepending option6 to any DHCPv6 option is # indicated as required in the dnsmasq man page for version 2.79. # Testing reveals that the man page is correct, option is not diff --git a/neutron/tests/unit/agent/linux/test_dhcp.py b/neutron/tests/unit/agent/linux/test_dhcp.py index 26088979080..51dbd4a1951 100644 --- a/neutron/tests/unit/agent/linux/test_dhcp.py +++ b/neutron/tests/unit/agent/linux/test_dhcp.py @@ -309,7 +309,7 @@ class FakeRouterPort2(object): self.device_owner = constants.DEVICE_OWNER_ROUTER_INTF self.fixed_ips = [ FakeIPAllocation('192.168.1.1', - 'dddddddd-dddd-dddd-dddd-dddddddddddd')] + 'cccccccc-cccc-cccc-cccc-cccccccccccc')] self.dns_assignment = [FakeDNSAssignment('192.168.1.1')] self.mac_address = '00:00:0f:rr:rr:r2' self.device_id = 'fake_router_port2' @@ -404,6 +404,7 @@ class FakeV4Subnet(Dictable): class FakeV4Subnet2(FakeV4Subnet): def __init__(self): super(FakeV4Subnet2, self).__init__() + self.id = 'cccccccc-cccc-cccc-cccc-cccccccccccc' self.cidr = '192.168.1.0/24' self.gateway_ip = '192.168.1.1' self.host_routes = [] @@ -1287,23 +1288,23 @@ class TestDnsmasq(TestBase): else: seconds = 's' if has_static: - prefix = '--dhcp-range=set:tag%d,%s,static,%s,%s%s' - prefix6 = '--dhcp-range=set:tag%d,%s,static,%s,%s%s' + prefix = '--dhcp-range=set:subnet-%s,%s,static,%s,%s%s' + prefix6 = '--dhcp-range=set:subnet-%s,%s,static,%s,%s%s' elif has_stateless: - prefix = '--dhcp-range=set:tag%d,%s,%s,%s%s' - prefix6 = '--dhcp-range=set:tag%d,%s,%s,%s%s' + prefix = '--dhcp-range=set:subnet-%s,%s,%s,%s%s' + prefix6 = '--dhcp-range=set:subnet-%s,%s,%s,%s%s' possible_leases = 0 - for i, s in enumerate(network.subnets): + for s in network.subnets: if (s.ip_version != constants.IP_VERSION_6 or s.ipv6_address_mode == constants.DHCPV6_STATEFUL): if s.ip_version == constants.IP_VERSION_4: expected.extend([prefix % ( - i, s.cidr.split('/')[0], + s.id, s.cidr.split('/')[0], netaddr.IPNetwork(s.cidr).netmask, lease_duration, seconds)]) else: expected.extend([prefix6 % ( - i, s.cidr.split('/')[0], s.cidr.split('/')[1], + s.id, s.cidr.split('/')[0], s.cidr.split('/')[1], lease_duration, seconds)]) possible_leases += netaddr.IPNetwork(s.cidr).size @@ -1503,182 +1504,244 @@ class TestDnsmasq(TestBase): def test_output_opts_file(self): fake_v6 = '2001:0200:feed:7ac0::1' expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,20.0.0.1/24,20.0.0.1,' '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,20.0.0.1/24,20.0.0.1,' - '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:tag1,option6:dns-server,%s\n' - 'tag:tag1,option6:domain-search,openstacklocal').lstrip() % ( - '[' + fake_v6 + ']') + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,20.0.0.1/24,20.0.0.1,169.254.169.254/32,192.168.0.1,' + '0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1\n' + 'tag:subnet-ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'option6:dns-server,%s\n' + 'tag:subnet-ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'option6:domain-search,openstacklocal' + ).lstrip() % ('[' + fake_v6 + ']') self._test_output_opts_file(expected, FakeDualNetwork()) def test_output_opts_file_gateway_route(self): fake_v6 = '2001:0200:feed:7ac0::1' - expected = ('tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,' - '169.254.169.254/32,192.168.0.1,0.0.0.0/0,' - '192.168.0.1\ntag:tag0,249,169.254.169.254/32,' - '192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:tag1,option6:dns-server,%s\n' - 'tag:tag1,option6:domain-search,' - 'openstacklocal').lstrip() % ('[' + fake_v6 + ']') + expected = ( + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,' + '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1\n' + 'tag:subnet-ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'option6:dns-server,%s\n' + 'tag:subnet-ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'option6:domain-search,openstacklocal' + ).lstrip() % ('[' + fake_v6 + ']') self._test_output_opts_file(expected, FakeDualNetworkGatewayRoute()) def test_output_opts_file_multiple_agents_without_dns_provided(self): - expected = ('tag:tag0,option:classless-static-route,' - '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,169.254.169.254/32,192.168.0.1,0.0.0.0/0,' - '192.168.0.1\ntag:tag0,option:router,192.168.0.1\n' - 'tag:tag0,option:dns-server,192.168.0.5,' - '192.168.0.6').lstrip() + expected = ( + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,' + '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,192.168.0.5,192.168.0.6').lstrip() self._test_output_opts_file(expected, FakeV4MultipleAgentsWithoutDnsProvided()) def test_output_opts_file_agent_dns_provided(self): - expected = ('tag:tag0,option:classless-static-route,' - '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,169.254.169.254/32,192.168.0.1,0.0.0.0/0,' - '192.168.0.1\ntag:tag0,option:router,192.168.0.1' - ).lstrip() + expected = ( + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,' + '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1').lstrip() self._test_output_opts_file(expected, FakeV4AgentWithoutDnsProvided()) def test_output_opts_file_agent_with_many_dns_provided(self): - expected = ('tag:tag0,' - 'option:dns-server,2.2.2.2,9.9.9.9,1.1.1.1,3.3.3.3\n' - 'tag:tag0,option:classless-static-route,' - '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,169.254.169.254/32,192.168.0.1,0.0.0.0/0,' - '192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1').lstrip() + expected = ( + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,2.2.2.2,9.9.9.9,1.1.1.1,3.3.3.3\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,' + '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1').lstrip() self._test_output_opts_file(expected, FakeV4AgentWithManyDnsProvided()) def test_output_opts_file_agent_with_no_dns_provided(self): - expected = ('tag:tag0,' - 'option:dns-server\n' - 'tag:tag0,option:classless-static-route,' - '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,169.254.169.254/32,192.168.0.1,0.0.0.0/0,' - '192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1').lstrip() + expected = ( + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,' + '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1').lstrip() self._test_output_opts_file(expected, FakeV4AgentWithNoDnsProvided()) def test_output_opts_file_multiple_agents_with_dns_provided(self): - expected = ('tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,' - '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,169.254.169.254/32,192.168.0.1,0.0.0.0/0,' - '192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1').lstrip() + expected = ( + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,' + '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1').lstrip() self._test_output_opts_file(expected, FakeV4MultipleAgentsWithDnsProvided()) def test_output_opts_file_single_dhcp(self): expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,192.168.1.0/24,0.0.0.0,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,192.168.1.0/24,0.0.0.0,' '20.0.0.1/24,20.0.0.1,169.254.169.254/32,192.168.0.1,' '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,192.168.1.0/24,0.0.0.0,' - '20.0.0.1/24,20.0.0.1,169.254.169.254/32,192.168.0.1,' - '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1').lstrip() + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,192.168.1.0/24,0.0.0.0,20.0.0.1/24,20.0.0.1,' + '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1').lstrip() self._test_output_opts_file(expected, FakeDualNetworkSingleDHCP()) def test_output_opts_file_single_dhcp_both_not_isolated(self): expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,20.0.0.1/24,20.0.0.1,' '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,20.0.0.1/24,20.0.0.1,' - '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1').lstrip() + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,20.0.0.1/24,20.0.0.1,169.254.169.254/32,192.168.0.1,' + '0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1').lstrip() self._test_output_opts_file(expected, FakeDualNetworkSingleDHCPBothAttaced()) def test_output_opts_file_dual_dhcp_rfc3442(self): expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,192.168.1.0/24,0.0.0.0,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,192.168.1.0/24,0.0.0.0,' '20.0.0.1/24,20.0.0.1,169.254.169.254/32,192.168.0.1,' '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,192.168.1.0/24,0.0.0.0,' - '20.0.0.1/24,20.0.0.1,169.254.169.254/32,192.168.0.1,' - '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:tag1,option:dns-server,8.8.8.8\n' - 'tag:tag1,option:classless-static-route,192.168.0.0/24,0.0.0.0,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,192.168.1.0/24,0.0.0.0,20.0.0.1/24,20.0.0.1,' + '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1\n' + 'tag:subnet-cccccccc-cccc-cccc-cccc-cccccccccccc,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-cccccccc-cccc-cccc-cccc-cccccccccccc,' + 'option:classless-static-route,192.168.0.0/24,0.0.0.0,' '169.254.169.254/32,192.168.1.1,0.0.0.0/0,192.168.1.1\n' - 'tag:tag1,249,192.168.0.0/24,0.0.0.0,' - '169.254.169.254/32,192.168.1.1,0.0.0.0/0,192.168.1.1\n' - 'tag:tag1,option:router,192.168.1.1').lstrip() + 'tag:subnet-cccccccc-cccc-cccc-cccc-cccccccccccc,' + '249,192.168.0.0/24,0.0.0.0,169.254.169.254/32,192.168.1.1,' + '0.0.0.0/0,192.168.1.1\n' + 'tag:subnet-cccccccc-cccc-cccc-cccc-cccccccccccc,' + 'option:router,192.168.1.1').lstrip() self._test_output_opts_file(expected, FakeDualNetworkDualDHCP()) def test_output_opts_file_dual_dhcp_rfc3442_no_on_link_subnet_routes(self): expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,20.0.0.1/24,20.0.0.1,' '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,20.0.0.1/24,20.0.0.1,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,20.0.0.1/24,20.0.0.1,' '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:tag1,option:dns-server,8.8.8.8\n' - 'tag:tag1,option:classless-static-route,' - '169.254.169.254/32,192.168.2.1,0.0.0.0/0,192.168.2.1\n' - 'tag:tag1,249,169.254.169.254/32,192.168.2.1,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1\n' + 'tag:subnet-iiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-iiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii,' + 'option:classless-static-route,169.254.169.254/32,192.168.2.1,' '0.0.0.0/0,192.168.2.1\n' - 'tag:tag1,option:router,192.168.2.1').lstrip() + 'tag:subnet-iiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii,' + '249,169.254.169.254/32,192.168.2.1,0.0.0.0/0,192.168.2.1\n' + 'tag:subnet-iiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii,' + 'option:router,192.168.2.1').lstrip() self._test_output_opts_file(expected, FakeDualNetworkDualDHCPOnLinkSubnetRoutesDisabled()) def test_output_opts_file_dual_dhcp_rfc3442_one_on_link_subnet_route(self): expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,192.168.1.0/24,0.0.0.0,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,192.168.1.0/24,0.0.0.0,' '20.0.0.1/24,20.0.0.1,169.254.169.254/32,192.168.0.1,' '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,192.168.1.0/24,0.0.0.0,' - '20.0.0.1/24,20.0.0.1,169.254.169.254/32,192.168.0.1,' - '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:tag1,option:dns-server,8.8.8.8\n' - 'tag:tag1,option:classless-static-route,192.168.0.0/24,0.0.0.0,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,192.168.1.0/24,0.0.0.0,20.0.0.1/24,20.0.0.1,' + '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1\n' + 'tag:subnet-cccccccc-cccc-cccc-cccc-cccccccccccc,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-cccccccc-cccc-cccc-cccc-cccccccccccc,' + 'option:classless-static-route,192.168.0.0/24,0.0.0.0,' '169.254.169.254/32,192.168.1.1,0.0.0.0/0,192.168.1.1\n' - 'tag:tag1,249,192.168.0.0/24,0.0.0.0,' - '169.254.169.254/32,192.168.1.1,0.0.0.0/0,192.168.1.1\n' - 'tag:tag1,option:router,192.168.1.1\n' - 'tag:tag2,option:dns-server,8.8.8.8\n' - 'tag:tag2,option:classless-static-route,' - '169.254.169.254/32,192.168.2.1,0.0.0.0/0,192.168.2.1\n' - 'tag:tag2,249,169.254.169.254/32,192.168.2.1,' + 'tag:subnet-cccccccc-cccc-cccc-cccc-cccccccccccc,' + '249,192.168.0.0/24,0.0.0.0,169.254.169.254/32,192.168.1.1,' + '0.0.0.0/0,192.168.1.1\n' + 'tag:subnet-cccccccc-cccc-cccc-cccc-cccccccccccc,' + 'option:router,192.168.1.1\n' + 'tag:subnet-iiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-iiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii,' + 'option:classless-static-route,169.254.169.254/32,192.168.2.1,' '0.0.0.0/0,192.168.2.1\n' - 'tag:tag2,option:router,192.168.2.1').lstrip() + 'tag:subnet-iiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii,' + '249,169.254.169.254/32,192.168.2.1,0.0.0.0/0,192.168.2.1\n' + 'tag:subnet-iiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii,' + 'option:router,192.168.2.1').lstrip() self._test_output_opts_file(expected, FakeDualNetworkTriDHCPOneOnLinkSubnetRoute()) def test_output_opts_file_no_gateway(self): expected = ( - 'tag:tag0,option:classless-static-route,' - '169.254.169.254/32,192.168.1.1\n' - 'tag:tag0,249,169.254.169.254/32,192.168.1.1\n' - 'tag:tag0,option:router').lstrip() + 'tag:subnet-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'option:classless-static-route,169.254.169.254/32,192.168.1.1\n' + 'tag:subnet-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + '249,169.254.169.254/32,192.168.1.1\n' + 'tag:subnet-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'option:router').lstrip() ipm_retval = {FakeV4SubnetNoGateway().id: '192.168.1.1'} self._test_output_opts_file(expected, FakeV4NoGatewayNetwork(), @@ -1686,28 +1749,37 @@ class TestDnsmasq(TestBase): def test_non_local_subnets(self): expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,' - '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,169.254.169.254/32,192.168.0.1,' - '0.0.0.0/0,192.168.0.1\ntag:tag0,option:router,192.168.0.1\n' - 'tag:tag1,option:dns-server,8.8.8.8\n' - 'tag:tag1,option:classless-static-route,' - '169.254.169.254/32,192.168.2.1,0.0.0.0/0,192.168.2.1\n' - 'tag:tag1,249,169.254.169.254/32,192.168.2.1,' + 'tag:subnet-jjjjjjjj-jjjj-jjjj-jjjj-jjjjjjjjjjjj,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-jjjjjjjj-jjjj-jjjj-jjjj-jjjjjjjjjjjj,' + 'option:classless-static-route,169.254.169.254/32,192.168.0.1,' + '0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-jjjjjjjj-jjjj-jjjj-jjjj-jjjjjjjjjjjj,' + '249,169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-jjjjjjjj-jjjj-jjjj-jjjj-jjjjjjjjjjjj,' + 'option:router,192.168.0.1\n' + 'tag:subnet-iiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-iiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii,' + 'option:classless-static-route,169.254.169.254/32,192.168.2.1,' '0.0.0.0/0,192.168.2.1\n' - 'tag:tag1,option:router,192.168.2.1').lstrip() + 'tag:subnet-iiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii,' + '249,169.254.169.254/32,192.168.2.1,0.0.0.0/0,192.168.2.1\n' + 'tag:subnet-iiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii,' + 'option:router,192.168.2.1').lstrip() ipm_retval = {FakeV4SubnetSegmentID2().id: '192.168.0.1'} self._test_output_opts_file(expected, FakeNonLocalSubnets(), ipm_retval=ipm_retval) def test_output_opts_file_no_neutron_router_on_subnet(self): expected = ( - 'tag:tag0,option:classless-static-route,' + 'tag:subnet-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'option:classless-static-route,' '169.254.169.254/32,192.168.1.2,0.0.0.0/0,192.168.1.1\n' - 'tag:tag0,249,169.254.169.254/32,192.168.1.2,' - '0.0.0.0/0,192.168.1.1\n' - 'tag:tag0,option:router,192.168.1.1').lstrip() + 'tag:subnet-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + '249,169.254.169.254/32,192.168.1.2,0.0.0.0/0,192.168.1.1\n' + 'tag:subnet-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'option:router,192.168.1.1').lstrip() ipm_retval = {FakeV4SubnetNoRouter().id: '192.168.1.2'} self._test_output_opts_file(expected, FakeV4NetworkNoRouter(), @@ -1715,12 +1787,16 @@ class TestDnsmasq(TestBase): def test_output_opts_file_dist_neutron_router_on_subnet(self): expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,20.0.0.1/24,20.0.0.1,' '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,20.0.0.1/24,20.0.0.1,' - '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1').lstrip() + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,20.0.0.1/24,20.0.0.1,169.254.169.254/32,192.168.0.1,' + '0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1').lstrip() ipm_retval = {FakeV4Subnet().id: '192.168.0.1'} self._test_output_opts_file(expected, FakeV4NetworkDistRouter(), @@ -1728,46 +1804,54 @@ class TestDnsmasq(TestBase): def test_output_opts_file_pxe_2port_1net(self): expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,20.0.0.1/24,20.0.0.1,' '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,20.0.0.1/24,20.0.0.1,' - '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,20.0.0.1/24,20.0.0.1,169.254.169.254/32,192.168.0.1,' + '0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1\n' + 'tag:port-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' 'option:tftp-server,192.168.0.3\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'tag:port-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' 'option:server-ip-address,192.168.0.2\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'tag:port-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' 'option:bootfile-name,pxelinux.0\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'tag:port-ffffffff-ffff-ffff-ffff-ffffffffffff,' 'option:tftp-server,192.168.0.3\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'tag:port-ffffffff-ffff-ffff-ffff-ffffffffffff,' 'option:server-ip-address,192.168.0.2\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'tag:port-ffffffff-ffff-ffff-ffff-ffffffffffff,' 'option:bootfile-name,pxelinux.0').lstrip() self._test_output_opts_file(expected, FakeV4NetworkPxe2Ports()) def test_output_opts_file_pxe_2port_1net_diff_details(self): expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,20.0.0.1/24,20.0.0.1,' '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,20.0.0.1/24,20.0.0.1,' - '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,20.0.0.1/24,20.0.0.1,169.254.169.254/32,192.168.0.1,' + '0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1\n' + 'tag:port-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' 'option:tftp-server,192.168.0.3\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'tag:port-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' 'option:server-ip-address,192.168.0.2\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'tag:port-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' 'option:bootfile-name,pxelinux.0\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'tag:port-ffffffff-ffff-ffff-ffff-ffffffffffff,' 'option:tftp-server,192.168.0.5\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'tag:port-ffffffff-ffff-ffff-ffff-ffffffffffff,' 'option:server-ip-address,192.168.0.5\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'tag:port-ffffffff-ffff-ffff-ffff-ffffffffffff,' 'option:bootfile-name,pxelinux.0').lstrip() self._test_output_opts_file(expected, @@ -1775,65 +1859,74 @@ class TestDnsmasq(TestBase): def test_output_opts_file_pxe_3port_2net(self): expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,192.168.1.0/24,0.0.0.0,' - '20.0.0.1/24,20.0.0.1,169.254.169.254/32,192.168.0.1,' - '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,192.168.1.0/24,0.0.0.0,' - '20.0.0.1/24,20.0.0.1,169.254.169.254/32,192.168.0.1,' - '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,192.168.1.0/24,0.0.0.0,20.0.0.1/24,' + '20.0.0.1,169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,192.168.1.0/24,0.0.0.0,20.0.0.1/24,20.0.0.1,' + '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1\n' + 'tag:port-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' 'option:tftp-server,192.168.0.3\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'tag:port-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' 'option:server-ip-address,192.168.0.2\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'tag:port-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' 'option:bootfile-name,pxelinux.0\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'tag:port-ffffffff-ffff-ffff-ffff-ffffffffffff,' 'option:tftp-server,192.168.1.3\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'tag:port-ffffffff-ffff-ffff-ffff-ffffffffffff,' 'option:server-ip-address,192.168.1.2\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'tag:port-ffffffff-ffff-ffff-ffff-ffffffffffff,' 'option:bootfile-name,pxelinux2.0\n' - 'tag:44444444-4444-4444-4444-444444444444,' + 'tag:port-44444444-4444-4444-4444-444444444444,' 'option:tftp-server,192.168.1.3\n' - 'tag:44444444-4444-4444-4444-444444444444,' + 'tag:port-44444444-4444-4444-4444-444444444444,' 'option:server-ip-address,192.168.1.2\n' - 'tag:44444444-4444-4444-4444-444444444444,' + 'tag:port-44444444-4444-4444-4444-444444444444,' 'option:bootfile-name,pxelinux3.0').lstrip() self._test_output_opts_file(expected, FakeDualV4Pxe3Ports()) def test_output_opts_file_pxe_port(self): expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,20.0.0.1/24,20.0.0.1,' '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,20.0.0.1/24,20.0.0.1,' - '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,20.0.0.1/24,20.0.0.1,0.0.0.0/0,192.168.0.1\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1\n' + 'tag:port-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' 'option:tftp-server,192.168.0.3\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'tag:port-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' 'option:server-ip-address,192.168.0.2\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'tag:port-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' 'option:nd98,option-nondigit-98\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'tag:port-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' '99,option-99\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'tag:port-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' 'option:bootfile-name,pxelinux.0').lstrip() self._test_output_opts_file(expected, FakeV4NetworkPxePort()) def test_output_opts_file_multiple_tags(self): expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,20.0.0.1/24,20.0.0.1,' '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,20.0.0.1/24,20.0.0.1,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,20.0.0.1/24,20.0.0.1,' '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1\n' + 'tag:port-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' 'tag:ipxe,option:bootfile-name,pxelinux.0') expected = expected.lstrip() @@ -1849,15 +1942,17 @@ class TestDnsmasq(TestBase): def test_output_opts_file_pxe_ipv6_port_with_ipv6_opt(self, mock_get_conf_fn): expected = ( - 'tag:tag0,option6:dns-server,[2001:0200:feed:7ac0::1]\n' - 'tag:tag0,option6:domain-search,openstacklocal\n' - 'tag:hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,' + 'tag:subnet-ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'option6:dns-server,[2001:0200:feed:7ac0::1]\n' + 'tag:subnet-ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'option6:domain-search,openstacklocal\n' + 'tag:port-hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,' 'option6:tftp-server,2001:192:168::1\n' - 'tag:hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,' + 'tag:port-hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,' 'option6:nd98,option-nondigit-98\n' - 'tag:hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,' + 'tag:port-hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,' 'option6:99,option-99\n' - 'tag:hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,' + 'tag:port-hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,' 'option6:bootfile-name,pxelinux.0') expected = expected.lstrip() @@ -1871,9 +1966,11 @@ class TestDnsmasq(TestBase): def test_output_opts_file_pxe_ipv6_port_with_ipv4_opt(self, mock_get_conf_fn): expected = ( - 'tag:tag0,option6:dns-server,[2001:0200:feed:7ac0::1]\n' - 'tag:tag0,option6:domain-search,openstacklocal\n' - 'tag:hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,' + 'tag:subnet-ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'option6:dns-server,[2001:0200:feed:7ac0::1]\n' + 'tag:subnet-ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'option6:domain-search,openstacklocal\n' + 'tag:port-hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,' 'option6:bootfile-name,pxelinux.0') expected = expected.lstrip() @@ -1885,8 +1982,10 @@ class TestDnsmasq(TestBase): def test_output_opts_file_ipv6_address_mode_unset(self): fake_v6 = '2001:0200:feed:7ac0::1' expected = ( - 'tag:tag0,option6:dns-server,%s\n' - 'tag:tag0,option6:domain-search,openstacklocal').lstrip() % ( + 'tag:subnet-ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'option6:dns-server,%s\n' + 'tag:subnet-ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'option6:domain-search,openstacklocal').lstrip() % ( '[' + fake_v6 + ']') self._test_output_opts_file(expected, FakeV6Network()) @@ -1894,8 +1993,10 @@ class TestDnsmasq(TestBase): def test_output_opts_file_ipv6_address_force_metadata(self): fake_v6 = '2001:0200:feed:7ac0::1' expected = ( - 'tag:tag0,option6:dns-server,%s\n' - 'tag:tag0,option6:domain-search,openstacklocal').lstrip() % ( + 'tag:subnet-ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'option6:dns-server,%s\n' + 'tag:subnet-ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'option6:domain-search,openstacklocal').lstrip() % ( '[' + fake_v6 + ']') self.conf.force_metadata = True self._test_output_opts_file(expected, FakeV6Network()) @@ -1964,14 +2065,20 @@ class TestDnsmasq(TestBase): exp_opt_name = '/dhcp/cccccccc-cccc-cccc-cccc-cccccccccccc/opts' fake_v6 = '2001:0200:feed:7ac0::1' exp_opt_data = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,20.0.0.1/24,20.0.0.1,' '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,20.0.0.1/24,20.0.0.1,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,20.0.0.1/24,20.0.0.1,' '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:tag1,option6:dns-server,%s\n' - 'tag:tag1,option6:domain-search,openstacklocal').lstrip() % ( + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1\n' + 'tag:subnet-ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'option6:dns-server,%s\n' + 'tag:subnet-ffffffff-ffff-ffff-ffff-ffffffffffff,' + 'option6:domain-search,openstacklocal').lstrip() % ( '[' + fake_v6 + ']') return (exp_host_name, exp_host_data, exp_addn_name, exp_addn_data, @@ -2612,14 +2719,15 @@ class TestDnsmasq(TestBase): def test_only_populates_dhcp_client_id(self): exp_host_name = '/dhcp/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/host' - exp_host_data = ('00:00:80:aa:bb:cc,host-192-168-0-2.openstacklocal.,' - '192.168.0.2\n' - '00:00:0f:aa:bb:55,id:test5,' - 'host-192-168-0-5.openstacklocal.,' - '192.168.0.5\n' - '00:00:0f:aa:bb:66,id:test6,' - 'host-192-168-0-6.openstacklocal.,192.168.0.6,' - 'set:ccccccccc-cccc-cccc-cccc-ccccccccc\n').lstrip() + exp_host_data = ( + '00:00:80:aa:bb:cc,host-192-168-0-2.openstacklocal.,' + '192.168.0.2\n' + '00:00:0f:aa:bb:55,id:test5,' + 'host-192-168-0-5.openstacklocal.,' + '192.168.0.5\n' + '00:00:0f:aa:bb:66,id:test6,' + 'host-192-168-0-6.openstacklocal.,192.168.0.6,' + 'set:port-ccccccccc-cccc-cccc-cccc-ccccccccc\n').lstrip() dm = self._get_dnsmasq(FakeV4NetworkClientId()) dm._output_hosts_file() @@ -2643,11 +2751,13 @@ class TestDnsmasq(TestBase): 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_host_data = ( + '00:16:3e:c2:77:1d,' + 'set:port-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,' + exp_opt_data = ('tag:subnet-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'option6:domain-search,openstacklocal\n' + 'tag:port-hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,' 'option6:dns-server,ffea:3ba5:a17a:4ba3::100').lstrip() dm = self._get_dnsmasq(FakeV6NetworkStatelessDHCP()) dm._output_hosts_file() @@ -2658,8 +2768,9 @@ class TestDnsmasq(TestBase): def test_host_and_opts_file_on_stateless_dhcpv6_network_no_dns(self): exp_host_name = '/dhcp/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb/host' exp_opt_name = '/dhcp/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb/opts' - exp_opt_data = ('tag:tag0,option6:dns-server\n' - 'tag:tag0,' + exp_opt_data = ('tag:subnet-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'option6:dns-server\n' + 'tag:subnet-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' 'option6:domain-search,openstacklocal').lstrip() dm = self._get_dnsmasq(FakeV6NetworkStatelessDHCPNoDnsProvided()) dm._output_hosts_file() @@ -2671,11 +2782,11 @@ class TestDnsmasq(TestBase): exp_host_name = '/dhcp/eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee/host' exp_host_data = ( '00:00:80:aa:bb:cc,host-192-168-0-2.openstacklocal.,192.168.0.2,' - 'set:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee\n' + 'set:port-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee\n' '00:16:3E:C2:77:1D,host-192-168-0-4.openstacklocal.,192.168.0.4,' - 'set:gggggggg-gggg-gggg-gggg-gggggggggggg\n00:00:0f:rr:rr:rr,' + 'set:port-gggggggg-gggg-gggg-gggg-gggggggggggg\n00:00:0f:rr:rr:rr,' 'host-192-168-0-1.openstacklocal.,192.168.0.1,' - 'set:rrrrrrrr-rrrr-rrrr-rrrr-rrrrrrrrrrrr\n').lstrip() + 'set:port-rrrrrrrr-rrrr-rrrr-rrrr-rrrrrrrrrrrr\n').lstrip() dm = self._get_dnsmasq(FakeDualStackNetworkingSingleDHCPTags()) dm._output_hosts_file() self.safe.assert_has_calls([mock.call(exp_host_name, exp_host_data)]) @@ -2684,21 +2795,26 @@ class TestDnsmasq(TestBase): 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' + '00:16:3e:c2:77:1d,set:port-hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh\n' '00:16:3e:c2:77:1d,host-192-168-0-3.openstacklocal.,' - '192.168.0.3,set:hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh\n' + '192.168.0.3,set:port-hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh\n' '00:00:0f:rr:rr:rr,' 'host-192-168-0-1.openstacklocal.,192.168.0.1\n').lstrip() exp_opt_name = '/dhcp/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb/opts' exp_opt_data = ( - 'tag:tag0,option6:domain-search,openstacklocal\n' - 'tag:tag1,option:dns-server,8.8.8.8\n' - 'tag:tag1,option:classless-static-route,20.0.0.1/24,20.0.0.1,' + 'tag:subnet-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' + 'option6:domain-search,openstacklocal\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:dns-server,8.8.8.8\n' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:classless-static-route,20.0.0.1/24,20.0.0.1,' '169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag1,249,20.0.0.1/24,20.0.0.1,169.254.169.254/32,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + '249,20.0.0.1/24,20.0.0.1,169.254.169.254/32,' '192.168.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag1,option:router,192.168.0.1\n' - 'tag:hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,' + 'tag:subnet-dddddddd-dddd-dddd-dddd-dddddddddddd,' + 'option:router,192.168.0.1\n' + 'tag:port-hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,' 'option6:dns-server,ffea:3ba5:a17a:4ba3::100').lstrip() dm = self._get_dnsmasq(FakeNetworkWithV6SatelessAndV4DHCPSubnets())