summaryrefslogtreecommitdiff
path: root/ironic/dhcp/neutron.py
diff options
context:
space:
mode:
authorDmitry Tantsur <divius.inside@gmail.com>2016-08-10 14:46:37 +0200
committerDmitry Tantsur <divius.inside@gmail.com>2016-08-11 12:56:42 +0200
commitf4ff926ab161297d2281394689ea25a7ef10cbb1 (patch)
treedecf403f6175b288b5333036a906391dc4c721fe /ironic/dhcp/neutron.py
parent98d373afe8045378c00cbd72a1637ca7a146936f (diff)
downloadironic-f4ff926ab161297d2281394689ea25a7ef10cbb1.tar.gz
Fix updating port MAC address for active nodes
Current update fails with HTTP 500 when trying to update a bound Neutron port. Remove the binding before update and restore it during update. For nodes in "active" state (or with instance_uuid assigned) only allow such update in maintenance mode. This is not a breaking change, as previously it did not work at all. Change-Id: I356fc0eb3702eb16b7f8e675ea416473c65af7e3 Closes-Bug: #1611744
Diffstat (limited to 'ironic/dhcp/neutron.py')
-rw-r--r--ironic/dhcp/neutron.py24
1 files changed, 24 insertions, 0 deletions
diff --git a/ironic/dhcp/neutron.py b/ironic/dhcp/neutron.py
index 0ebe00042..021af95b7 100644
--- a/ironic/dhcp/neutron.py
+++ b/ironic/dhcp/neutron.py
@@ -70,6 +70,16 @@ class NeutronDHCPApi(base.BaseDHCP):
LOG.exception(_LE("Failed to update Neutron port %s."), port_id)
raise exception.FailedToUpdateDHCPOptOnPort(port_id=port_id)
+ def _get_binding(self, client, port_id):
+ """Get binding:host_id property from Neutron."""
+ try:
+ return client.show_port(port_id).get('port', {}).get(
+ 'binding:host_id')
+ except neutron_client_exc.NeutronClientException:
+ LOG.exception(_LE('Failed to get the current binding on Neutron '
+ 'port %s.'), port_id)
+ raise exception.FailedToUpdateMacOnPort(port_id=port_id)
+
def update_port_address(self, port_id, address, token=None):
"""Update a port's mac address.
@@ -78,7 +88,21 @@ class NeutronDHCPApi(base.BaseDHCP):
:param token: optional auth token.
:raises: FailedToUpdateMacOnPort
"""
+ client = neutron.get_client(token)
port_req_body = {'port': {'mac_address': address}}
+
+ current_binding = self._get_binding(client, port_id)
+ if current_binding:
+ binding_clean_body = {'port': {'binding:host_id': ''}}
+ try:
+ client.update_port(port_id, binding_clean_body)
+ except neutron_client_exc.NeutronClientException:
+ LOG.exception(_LE("Failed to remove the current binding from "
+ "Neutron port %s."), port_id)
+ raise exception.FailedToUpdateMacOnPort(port_id=port_id)
+
+ port_req_body['port']['binding:host_id'] = current_binding
+
try:
neutron.get_client(token).update_port(port_id, port_req_body)
except neutron_client_exc.NeutronClientException: