diff --git a/ovn_octavia_provider/helper.py b/ovn_octavia_provider/helper.py index 4edd1487..15eeb0e4 100644 --- a/ovn_octavia_provider/helper.py +++ b/ovn_octavia_provider/helper.py @@ -888,27 +888,49 @@ class OvnProviderHelper(): def lb_create(self, loadbalancer, protocol=None): port = None subnet = {} - neutron_client = clients.get_neutron_client() - if loadbalancer.get(constants.VIP_PORT_ID): - # In case we don't have vip_network_id - port = neutron_client.show_port( - loadbalancer[constants.VIP_PORT_ID])['port'] - for ip in port['fixed_ips']: - if ip['ip_address'] == loadbalancer[constants.VIP_ADDRESS]: - subnet = neutron_client.show_subnet( - ip['subnet_id'])['subnet'] - break - elif (loadbalancer.get(constants.VIP_NETWORK_ID) and - loadbalancer.get(constants.VIP_ADDRESS)): - ports = neutron_client.list_ports( - network_id=loadbalancer[constants.VIP_NETWORK_ID]) - for p in ports['ports']: - for ip in p['fixed_ips']: + try: + neutron_client = clients.get_neutron_client() + if loadbalancer.get(constants.VIP_PORT_ID): + # In case we don't have vip_network_id + port = neutron_client.show_port( + loadbalancer[constants.VIP_PORT_ID])['port'] + for ip in port['fixed_ips']: if ip['ip_address'] == loadbalancer[constants.VIP_ADDRESS]: - port = p subnet = neutron_client.show_subnet( ip['subnet_id'])['subnet'] break + elif (loadbalancer.get(constants.VIP_NETWORK_ID) and + loadbalancer.get(constants.VIP_ADDRESS)): + ports = neutron_client.list_ports( + network_id=loadbalancer[constants.VIP_NETWORK_ID]) + for p in ports['ports']: + for ip in p['fixed_ips']: + if ip['ip_address'] == loadbalancer[ + constants.VIP_ADDRESS]: + port = p + subnet = neutron_client.show_subnet( + ip['subnet_id'])['subnet'] + break + except Exception: + LOG.error('Cannot get info from neutron client') + LOG.exception(ovn_const.EXCEPTION_MSG, "creation of loadbalancer") + # Any Exception set the status to ERROR + if isinstance(port, dict): + try: + self.delete_vip_port(port.get('id')) + LOG.warning("Deleting the VIP port %s since LB went into " + "ERROR state", str(port.get('id'))) + except Exception: + LOG.exception("Error deleting the VIP port %s upon " + "loadbalancer %s creation failure", + str(port.get('id')), + str(loadbalancer[constants.ID])) + status = { + constants.LOADBALANCERS: [ + {constants.ID: loadbalancer[constants.ID], + constants.PROVISIONING_STATUS: constants.ERROR, + constants.OPERATING_STATUS: constants.ERROR}]} + return status # If protocol set make sure its lowercase protocol = protocol.lower() if protocol else [] diff --git a/ovn_octavia_provider/tests/unit/test_helper.py b/ovn_octavia_provider/tests/unit/test_helper.py index 0c5f5895..89084c84 100644 --- a/ovn_octavia_provider/tests/unit/test_helper.py +++ b/ovn_octavia_provider/tests/unit/test_helper.py @@ -632,6 +632,16 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase): def test_lb_create_on_multi_protocol_SCTP(self): self._test_lb_create_on_multi_protocol('SCTP') + @mock.patch('ovn_octavia_provider.common.clients.get_neutron_client') + def test_lb_create_neutron_client_exception(self, net_cli): + net_cli.return_value.list_ports.return_value = self.ports + net_cli.return_value.show_subnet.side_effect = [n_exc.NotFound] + status = self.helper.lb_create(self.lb) + self.assertEqual(status['loadbalancers'][0]['provisioning_status'], + constants.ERROR) + self.assertEqual(status['loadbalancers'][0]['operating_status'], + constants.ERROR) + @mock.patch('ovn_octavia_provider.common.clients.get_neutron_client') @mock.patch.object(ovn_helper.OvnProviderHelper, 'delete_vip_port') def test_lb_create_exception(self, del_port, net_cli):