diff --git a/neutron-powervc/powervc/neutron/agent/neutron_powervc_agent.py b/neutron-powervc/powervc/neutron/agent/neutron_powervc_agent.py index 87d51f3..9be3a05 100644 --- a/neutron-powervc/powervc/neutron/agent/neutron_powervc_agent.py +++ b/neutron-powervc/powervc/neutron/agent/neutron_powervc_agent.py @@ -519,10 +519,11 @@ class PowerVCNeutronAgent(object): db_port = self.db.create_port(port, sync_key, local_id=local_id) # Determine which instance owns this port device_id = port.get('device_id') - # Determine if the instance is (HyperV / KVM) or PowerVC + # Determine if the instance is (HyperV / KVM) or PowerVC or Lock Port # if PowerVC, return. - # If HyperV/KVM, reserve IP address in PowerVC - if not self.local.is_instance_on_power(device_id): + # If HyperV/KVM or Lock Port, reserve IP address in PowerVC + if device_id == constants.POWERVC_LOCKDEVICE_ID\ + or not self.local.is_instance_on_power(device_id): new_port = self.pvc.create_port(port) if new_port: self.db.set_port_pvc_id(db_port, new_port.get('id')) @@ -624,7 +625,8 @@ class PowerVCNeutronAgent(object): self.db.delete_port(db_port) return device_id = pvc_port.get('device_id') - if device_id and len(device_id) > 0: + if device_id and len(device_id) > 0\ + and device_id != constants.POWERVC_LOCKDEVICE_ID: LOG.info(_("PowerVC port %s can not be deleted. Port is in-use " "by VM %s."), pvc_id, device_id) LOG.info(_("Recreate the local port to prevent this IP " @@ -661,7 +663,7 @@ class PowerVCNeutronAgent(object): def _delete_local_port(self, local_port, db_port): # complex logic here on how to handle it # some possible cases for this local port: - # 1) device_id = None occurs when lock IP address done using SCE UI. + # 1) device_id = PowerVC-Lock occurs when lock IP address done. # Delete the local port # 2) device_owner = network:router_interface (see issue 173350). # re-create the PVC port @@ -1168,7 +1170,8 @@ class PowerVCNeutronAgent(object): self.db.delete_port(db_port) continue device_id = pvc_port.get('device_id') - if device_id and len(device_id) > 0: + if device_id and len(device_id) > 0\ + and device_id != constants.POWERVC_LOCKDEVICE_ID: LOG.info(_("PVC port %s can not be deleted. Port is " "in-use by VM %s."), pvc_id, device_id) LOG.info(_("Recreate the local port to prevent this IP " @@ -1206,7 +1209,8 @@ class PowerVCNeutronAgent(object): local_port = local_ports.get(local_id) # Determine which instance owns this port device_id = local_port.get('device_id') - if not self.local.is_instance_on_power(device_id): + if device_id == constants.POWERVC_LOCKDEVICE_ID\ + or not self.local.is_instance_on_power(device_id): # Create a port on PVC if this is a local instance, # so PVC won't use its IP address. pvc_port = self.pvc.create_port(local_port) diff --git a/neutron-powervc/powervc/neutron/client/local_os_bindings.py b/neutron-powervc/powervc/neutron/client/local_os_bindings.py index 2091252..a2bde64 100644 --- a/neutron-powervc/powervc/neutron/client/local_os_bindings.py +++ b/neutron-powervc/powervc/neutron/client/local_os_bindings.py @@ -227,7 +227,8 @@ class Client(neutron_client_bindings.Client): return False # Check to see if this is a reserved port that we created while we # are waiting for the PowerVC side to go away - if uuid.startswith(constants.RSVD_PORT_PREFIX): + if uuid.startswith(constants.RSVD_PORT_PREFIX)\ + or uuid == constants.POWERVC_LOCKDEVICE_ID: return False if not self.nova: diff --git a/neutron-powervc/powervc/neutron/client/neutron_client_bindings.py b/neutron-powervc/powervc/neutron/client/neutron_client_bindings.py index 625dc12..c04244f 100644 --- a/neutron-powervc/powervc/neutron/client/neutron_client_bindings.py +++ b/neutron-powervc/powervc/neutron/client/neutron_client_bindings.py @@ -92,11 +92,22 @@ class Client(base.ClientExtension): body[field] = port[field] if self.os == POWERVC_OS: body['device_owner'] = constants.POWERVC_DEVICE_OWNER + # Set device id to powervc locked when this port is bound to + # non PowerVC instances + if port.get('device_id'): + body['device_id'] = constants.POWERVC_LOCKDEVICE_ID elif port.get('device_id'): - # If we are creating a local port and the PowerVC port has a - # device id, then set the device id of the new local port to be - # "pvc:" + PowerVC device id. - body['device_id'] = constants.RSVD_PORT_PREFIX + port['device_id'] + dev_id = port['device_id'] + if dev_id == constants.POWERVC_LOCKDEVICE_ID: + # PowerVC locked port, simply synchronize them to local + body['device_id'] = dev_id + if port.get('device_owner'): + body['device_owner'] = port['device_owner'] + else: + # If we are creating a local port and the PowerVC port has a + # device id, then set the device id of the new local port to be + # "pvc:" + PowerVC device id. + body['device_id'] = constants.RSVD_PORT_PREFIX + dev_id fixed_ips = port.get('fixed_ips') if not fixed_ips: return None diff --git a/neutron-powervc/powervc/neutron/common/constants.py b/neutron-powervc/powervc/neutron/common/constants.py index 0abefe8..88f60dd 100644 --- a/neutron-powervc/powervc/neutron/common/constants.py +++ b/neutron-powervc/powervc/neutron/common/constants.py @@ -8,6 +8,7 @@ Created on Aug 2, 2013 # Device owner value for Neutron ports we create POWERVC_DEVICE_OWNER = 'network:IBM SmartCloud' +POWERVC_LOCKDEVICE_ID = 'PowerVC-Lock' RSVD_PORT_PREFIX = 'pvc:' # Mapping enum values