Merge "NSX|V3: ensure that subnet update takes host routes into account"
This commit is contained in:
commit
39b2821126
@ -1395,11 +1395,23 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
if (cfg.CONF.nsx_v3.native_dhcp_metadata and
|
||||
updated_subnet['enable_dhcp']):
|
||||
kwargs = {}
|
||||
for key in ('dns_nameservers', 'gateway_ip'):
|
||||
for key in ('dns_nameservers', 'gateway_ip', 'host_routes'):
|
||||
if key in subnet['subnet']:
|
||||
value = subnet['subnet'][key]
|
||||
if value != orig_subnet[key]:
|
||||
kwargs[key] = value
|
||||
if key != 'dns_nameservers':
|
||||
kwargs['options'] = None
|
||||
if 'options' in kwargs:
|
||||
sr, gw_ip = self.nsxlib.native_dhcp.build_static_routes(
|
||||
updated_subnet.get('gateway_ip'),
|
||||
updated_subnet.get('cidr'),
|
||||
updated_subnet.get('host_routes', []))
|
||||
kwargs['options'] = {'option121': {'static_routes': sr}}
|
||||
kwargs.pop('host_routes', None)
|
||||
if (gw_ip is not None and 'gateway_ip' not in kwargs and
|
||||
gw_ip != updated_subnet['gateway_ip']):
|
||||
kwargs['gateway_ip'] = gw_ip
|
||||
if kwargs:
|
||||
dhcp_service = nsx_db.get_nsx_service_binding(
|
||||
context.session, orig_subnet['network_id'],
|
||||
@ -1415,17 +1427,22 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
"%(server)s for network %(network)s",
|
||||
{'server': dhcp_service['nsx_service_id'],
|
||||
'network': orig_subnet['network_id']})
|
||||
if 'gateway_ip' in kwargs:
|
||||
if 'options' in kwargs:
|
||||
# Need to update the static binding of every VM in
|
||||
# this logical DHCP server.
|
||||
bindings = nsx_db.get_nsx_dhcp_bindings_by_service(
|
||||
context.session, dhcp_service['nsx_service_id'])
|
||||
for binding in bindings:
|
||||
port = self._get_port(context, binding['port_id'])
|
||||
dhcp_opts = port.get(ext_edo.EXTRADHCPOPTS)
|
||||
self._update_dhcp_binding_on_server(
|
||||
context, binding, port['mac_address'],
|
||||
binding['ip_address'], kwargs['gateway_ip'],
|
||||
port['network_id'])
|
||||
binding['ip_address'],
|
||||
port['network_id'],
|
||||
gateway_ip=kwargs.get('gateway_ip', False),
|
||||
dhcp_opts=dhcp_opts,
|
||||
options=kwargs.get('options'),
|
||||
subnet=updated_subnet)
|
||||
|
||||
if (cfg.CONF.nsx_v3.metadata_on_demand and
|
||||
not cfg.CONF.nsx_v3.native_dhcp_metadata):
|
||||
@ -1792,12 +1809,18 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
msg = (_("DHCP option %s is not supported") % opt_name)
|
||||
raise n_exc.InvalidInput(error_message=msg)
|
||||
|
||||
def _get_dhcp_options(self, context, ip, extra_dhcp_opts, net_id):
|
||||
def _get_dhcp_options(self, context, ip, extra_dhcp_opts, net_id,
|
||||
subnet):
|
||||
# Always add option121.
|
||||
net_az = self.get_network_az_by_net_id(context, net_id)
|
||||
options = {'option121': {'static_routes': [
|
||||
{'network': '%s' % net_az.native_metadata_route,
|
||||
'next_hop': ip}]}}
|
||||
if subnet:
|
||||
sr, gateway_ip = self.nsxlib.native_dhcp.build_static_routes(
|
||||
subnet.get('gateway_ip'), subnet.get('cidr'),
|
||||
subnet.get('host_routes', []))
|
||||
options['option121']['static_routes'].extend(sr)
|
||||
# Adding extra options only if configured on port
|
||||
if extra_dhcp_opts:
|
||||
other_opts = []
|
||||
@ -1829,12 +1852,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
gateway_ip = subnet.get('gateway_ip')
|
||||
options = self._get_dhcp_options(
|
||||
context, ip, port.get(ext_edo.EXTRADHCPOPTS),
|
||||
port['network_id'])
|
||||
# update static routes
|
||||
for hr in subnet['host_routes']:
|
||||
options['option121']['static_routes'].append(
|
||||
{'network': hr['destination'],
|
||||
'next_hop': hr['nexthop']})
|
||||
port['network_id'], subnet)
|
||||
binding = self.nsxlib.dhcp_server.create_binding(
|
||||
dhcp_service_id, port['mac_address'], ip, hostname,
|
||||
cfg.CONF.nsx_v3.dhcp_lease_time, options, gateway_ip)
|
||||
@ -1969,10 +1987,12 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
binding = self._find_dhcp_binding(subnet_id, ip,
|
||||
bindings)
|
||||
if binding:
|
||||
subnet = self.get_subnet(context,
|
||||
binding['subnet_id'])
|
||||
self._update_dhcp_binding_on_server(
|
||||
context, binding, new_port['mac_address'],
|
||||
ips_to_add[i][1], old_port['network_id'],
|
||||
dhcp_opts=dhcp_opts)
|
||||
dhcp_opts=dhcp_opts, subnet=subnet)
|
||||
# Update DB IP
|
||||
nsx_db.update_nsx_dhcp_bindings(context.session,
|
||||
old_port['id'],
|
||||
@ -1999,23 +2019,28 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
# If only Mac address/dhcp opts is changed,
|
||||
# update it in all associated DHCP bindings.
|
||||
for binding in bindings:
|
||||
subnet = self.get_subnet(context, binding['subnet_id'])
|
||||
self._update_dhcp_binding_on_server(
|
||||
context, binding, new_port['mac_address'],
|
||||
binding['ip_address'], old_port['network_id'],
|
||||
dhcp_opts=dhcp_opts if dhcp_opts_changed else None)
|
||||
dhcp_opts=dhcp_opts, subnet=subnet)
|
||||
|
||||
def _update_dhcp_binding_on_server(self, context, binding, mac, ip,
|
||||
net_id, gateway_ip=False,
|
||||
dhcp_opts=None):
|
||||
dhcp_opts=None, options=None,
|
||||
subnet=None):
|
||||
try:
|
||||
data = {'mac_address': mac, 'ip_address': ip}
|
||||
if ip != binding['ip_address']:
|
||||
data['host_name'] = 'host-%s' % ip.replace('.', '-')
|
||||
data['options'] = self._get_dhcp_options(
|
||||
context, ip, dhcp_opts, net_id)
|
||||
elif dhcp_opts is not None:
|
||||
context, ip, dhcp_opts, net_id,
|
||||
subnet)
|
||||
elif (dhcp_opts is not None or
|
||||
options is not None):
|
||||
data['options'] = self._get_dhcp_options(
|
||||
context, ip, dhcp_opts, net_id)
|
||||
context, ip, dhcp_opts, net_id,
|
||||
subnet)
|
||||
if gateway_ip is not False:
|
||||
# Note that None is valid for gateway_ip, means deleting it.
|
||||
data['gateway_ip'] = gateway_ip
|
||||
|
@ -400,7 +400,11 @@ class NsxNativeDhcpTestCase(test_plugin.NsxV3PluginTestCaseMixin):
|
||||
options = {'option121': {'static_routes': [
|
||||
{'network': '%s' %
|
||||
cfg.CONF.nsx_v3.native_metadata_route,
|
||||
'next_hop': ip}]}}
|
||||
'next_hop': ip},
|
||||
{'network': subnet['subnet']['cidr'],
|
||||
'next_hop': '0.0.0.0'},
|
||||
{'network': '0.0.0.0/0',
|
||||
'next_hop': subnet['subnet']['gateway_ip']}]}}
|
||||
create_dhcp_binding.assert_called_once_with(
|
||||
dhcp_service['nsx_service_id'],
|
||||
port['port']['mac_address'], ip, hostname,
|
||||
@ -435,8 +439,12 @@ class NsxNativeDhcpTestCase(test_plugin.NsxV3PluginTestCaseMixin):
|
||||
options = {'option121': {'static_routes': [
|
||||
{'network': '%s' %
|
||||
cfg.CONF.nsx_v3.native_metadata_route,
|
||||
'next_hop': ip}]},
|
||||
'others': [{'code': opt_code, 'values': [opt_val]}]}
|
||||
'next_hop': ip},
|
||||
{'network': subnet['subnet']['cidr'],
|
||||
'next_hop': '0.0.0.0'},
|
||||
{'network': '0.0.0.0/0',
|
||||
'next_hop': subnet['subnet']['gateway_ip']}]},
|
||||
'others': [{'code': opt_code, 'values': [opt_val]}]}
|
||||
create_dhcp_binding.assert_called_once_with(
|
||||
dhcp_service['nsx_service_id'],
|
||||
port['port']['mac_address'], ip, hostname,
|
||||
@ -469,7 +477,12 @@ class NsxNativeDhcpTestCase(test_plugin.NsxV3PluginTestCaseMixin):
|
||||
{'network': '%s' %
|
||||
cfg.CONF.nsx_v3.native_metadata_route,
|
||||
'next_hop': ip},
|
||||
{'network': '1.0.0.0/24', 'next_hop': '1.2.3.4'}]}}
|
||||
{'network': subnet['subnet']['cidr'],
|
||||
'next_hop': '0.0.0.0'},
|
||||
{'network': '0.0.0.0/0',
|
||||
'next_hop': subnet['subnet']['gateway_ip']},
|
||||
{'network': '1.0.0.0/24',
|
||||
'next_hop': '1.2.3.4'}]}}
|
||||
create_dhcp_binding.assert_called_once_with(
|
||||
dhcp_service['nsx_service_id'],
|
||||
port['port']['mac_address'], ip, hostname,
|
||||
@ -595,7 +608,11 @@ class NsxNativeDhcpTestCase(test_plugin.NsxV3PluginTestCaseMixin):
|
||||
'options': {'option121': {'static_routes': [
|
||||
{'network': '%s' %
|
||||
cfg.CONF.nsx_v3.native_metadata_route,
|
||||
'next_hop': new_ip}]}}}
|
||||
'next_hop': new_ip},
|
||||
{'network': subnet['subnet']['cidr'],
|
||||
'next_hop': '0.0.0.0'},
|
||||
{'network': constants.IPv4_ANY,
|
||||
'next_hop': subnet['subnet']['gateway_ip']}]}}}
|
||||
self._verify_dhcp_binding(subnet, port_data, update_data,
|
||||
assert_data)
|
||||
|
||||
@ -606,7 +623,15 @@ class NsxNativeDhcpTestCase(test_plugin.NsxV3PluginTestCaseMixin):
|
||||
port_data = {'mac_address': '11:22:33:44:55:66'}
|
||||
new_mac = '22:33:44:55:66:77'
|
||||
update_data = {'port': {'mac_address': new_mac}}
|
||||
assert_data = {'mac_address': new_mac}
|
||||
assert_data = {'mac_address': new_mac,
|
||||
'options': {'option121': {'static_routes': [
|
||||
{'network': '%s' %
|
||||
cfg.CONF.nsx_v3.native_metadata_route,
|
||||
'next_hop': mock.ANY},
|
||||
{'network': subnet['subnet']['cidr'],
|
||||
'next_hop': '0.0.0.0'},
|
||||
{'network': constants.IPv4_ANY,
|
||||
'next_hop': subnet['subnet']['gateway_ip']}]}}}
|
||||
self._verify_dhcp_binding(subnet, port_data, update_data,
|
||||
assert_data)
|
||||
|
||||
@ -627,7 +652,11 @@ class NsxNativeDhcpTestCase(test_plugin.NsxV3PluginTestCaseMixin):
|
||||
'options': {'option121': {'static_routes': [
|
||||
{'network': '%s' %
|
||||
cfg.CONF.nsx_v3.native_metadata_route,
|
||||
'next_hop': new_ip}]}}}
|
||||
'next_hop': new_ip},
|
||||
{'network': subnet['subnet']['cidr'],
|
||||
'next_hop': '0.0.0.0'},
|
||||
{'network': constants.IPv4_ANY,
|
||||
'next_hop': subnet['subnet']['gateway_ip']}]}}}
|
||||
self._verify_dhcp_binding(subnet, port_data, update_data,
|
||||
assert_data)
|
||||
|
||||
@ -651,7 +680,11 @@ class NsxNativeDhcpTestCase(test_plugin.NsxV3PluginTestCaseMixin):
|
||||
'options': {'option121': {'static_routes': [
|
||||
{'network': '%s' %
|
||||
cfg.CONF.nsx_v3.native_metadata_route,
|
||||
'next_hop': ip_addr}]},
|
||||
'next_hop': ip_addr},
|
||||
{'network': subnet['subnet']['cidr'],
|
||||
'next_hop': '0.0.0.0'},
|
||||
{'network': constants.IPv4_ANY,
|
||||
'next_hop': subnet['subnet']['gateway_ip']}]},
|
||||
'others': [{'code': 26, 'values': ['9002']}]}}
|
||||
self._verify_dhcp_binding(subnet, port_data, update_data,
|
||||
assert_data)
|
||||
@ -676,7 +709,11 @@ class NsxNativeDhcpTestCase(test_plugin.NsxV3PluginTestCaseMixin):
|
||||
'options': {'option121': {'static_routes': [
|
||||
{'network': '%s' %
|
||||
cfg.CONF.nsx_v3.native_metadata_route,
|
||||
'next_hop': ip_addr}]},
|
||||
'next_hop': ip_addr},
|
||||
{'network': subnet['subnet']['cidr'],
|
||||
'next_hop': '0.0.0.0'},
|
||||
{'network': constants.IPv4_ANY,
|
||||
'next_hop': subnet['subnet']['gateway_ip']}]},
|
||||
'others': [{'code': 26, 'values': ['9002']},
|
||||
{'code': 40, 'values': ['abc']}]}}
|
||||
self._verify_dhcp_binding(subnet, port_data, update_data,
|
||||
@ -704,7 +741,11 @@ class NsxNativeDhcpTestCase(test_plugin.NsxV3PluginTestCaseMixin):
|
||||
'options': {'option121': {'static_routes': [
|
||||
{'network': '%s' %
|
||||
cfg.CONF.nsx_v3.native_metadata_route,
|
||||
'next_hop': ip_addr}]},
|
||||
'next_hop': ip_addr},
|
||||
{'network': subnet['subnet']['cidr'],
|
||||
'next_hop': '0.0.0.0'},
|
||||
{'network': constants.IPv4_ANY,
|
||||
'next_hop': subnet['subnet']['gateway_ip']}]},
|
||||
'others': [{'code': 40, 'values': ['abc']}]}}
|
||||
self._verify_dhcp_binding(subnet, port_data, update_data,
|
||||
assert_data)
|
||||
@ -849,8 +890,13 @@ class NsxNativeDhcpTestCase(test_plugin.NsxV3PluginTestCaseMixin):
|
||||
ip = port['port']['fixed_ips'][0]['ip_address']
|
||||
hostname = 'host-%s' % ip.replace('.', '-')
|
||||
options = {'option121': {'static_routes': [
|
||||
{'network': '%s' % self.az_metadata_route,
|
||||
'next_hop': ip}]}}
|
||||
{'network': '%s' %
|
||||
self.az_metadata_route,
|
||||
'next_hop': ip},
|
||||
{'network': subnet['subnet']['cidr'],
|
||||
'next_hop': '0.0.0.0'},
|
||||
{'network': '0.0.0.0/0',
|
||||
'next_hop': subnet['subnet']['gateway_ip']}]}}
|
||||
create_dhcp_binding.assert_called_once_with(
|
||||
dhcp_service['nsx_service_id'],
|
||||
port['port']['mac_address'], ip, hostname,
|
||||
|
Loading…
Reference in New Issue
Block a user