import json
from neutron.openstack.common import log
+from neutron.plugins.vmware.api_client import exception as api_exc
+from neutron.plugins.vmware.common import exceptions as nsx_exc
from neutron.plugins.vmware.common import utils
from neutron.plugins.vmware.nsxlib import _build_uri_path
from neutron.plugins.vmware.nsxlib import do_request
body = _build_gateway_device_body(tenant_id, display_name, neutron_id,
connector_type, connector_ip,
client_certificate, tz_uuid)
- return do_request(
- HTTP_POST, _build_uri_path(TRANSPORTNODE_RESOURCE),
- json.dumps(body), cluster=cluster)
+ try:
+ return do_request(
+ HTTP_POST, _build_uri_path(TRANSPORTNODE_RESOURCE),
+ json.dumps(body), cluster=cluster)
+ except api_exc.InvalidSecurityCertificate:
+ raise nsx_exc.InvalidSecurityCertificate()
def update_gateway_device(cluster, gateway_id, tenant_id,
body = _build_gateway_device_body(tenant_id, display_name, neutron_id,
connector_type, connector_ip,
client_certificate, tz_uuid)
- return do_request(
- HTTP_PUT,
- _build_uri_path(TRANSPORTNODE_RESOURCE, resource_id=gateway_id),
- json.dumps(body), cluster=cluster)
+ try:
+ return do_request(
+ HTTP_PUT,
+ _build_uri_path(TRANSPORTNODE_RESOURCE, resource_id=gateway_id),
+ json.dumps(body), cluster=cluster)
+ except api_exc.InvalidSecurityCertificate:
+ raise nsx_exc.InvalidSecurityCertificate()
def delete_gateway_device(cluster, device_uuid):
nsx_exc.NoMorePortsException:
webob.exc.HTTPBadRequest,
nsx_exc.MaintenanceInProgress:
- webob.exc.HTTPServiceUnavailable})
+ webob.exc.HTTPServiceUnavailable,
+ nsx_exc.InvalidSecurityCertificate:
+ webob.exc.HTTPBadRequest})
def _validate_provider_create(self, context, network):
if not attr.is_attr_set(network.get(mpnet.SEGMENTS)):
def _get_nsx_device_id(self, context, device_id):
return self._get_gateway_device(context, device_id)['nsx_id']
+ def _rollback_gw_device(self, context, device_id,
+ gw_data=None, new_status=None,
+ is_create=False, log_level=logging.ERROR):
+ LOG.log(log_level,
+ _("Rolling back database changes for gateway device %s "
+ "because of an error in the NSX backend"), device_id)
+ with context.session.begin(subtransactions=True):
+ query = self._model_query(
+ context, networkgw_db.NetworkGatewayDevice).filter(
+ networkgw_db.NetworkGatewayDevice.id == device_id)
+ if is_create:
+ query.delete(synchronize_session=False)
+ else:
+ super(NsxPluginV2, self).update_gateway_device(
+ context, device_id,
+ {networkgw.DEVICE_RESOURCE_NAME: gw_data})
+ if new_status:
+ query.update({'status': new_status},
+ synchronize_session=False)
+
# TODO(salv-orlando): Handlers for Gateway device operations should be
# moved into the appropriate nsx_handlers package once the code for the
# blueprint nsx-async-backend-communication merges
'nsx_id': nsx_res['uuid'],
'status': device_status})
return device_status
- except api_exc.NsxApiException:
- # Remove gateway device from neutron database
+ except (nsx_exc.InvalidSecurityCertificate, api_exc.NsxApiException):
with excutils.save_and_reraise_exception():
- LOG.exception(_("Unable to create gateway device: %s on NSX "
- "backend."), neutron_id)
- with context.session.begin(subtransactions=True):
- query = self._model_query(
- context, networkgw_db.NetworkGatewayDevice).filter(
- networkgw_db.NetworkGatewayDevice.id == neutron_id)
- query.delete(synchronize_session=False)
+ self._rollback_gw_device(context, neutron_id, is_create=True)
def update_gateway_device_handler(self, context, gateway_device,
old_gateway_device_data,
# Fetch status (it needs another NSX API call)
device_status = nsx_utils.get_nsx_device_status(self.cluster,
nsx_id)
-
# update status
with context.session.begin(subtransactions=True):
query = self._model_query(
'nsx_id': nsx_id,
'status': device_status})
return device_status
- except api_exc.NsxApiException:
- # Rollback gateway device on neutron database
- # As the NSX failure could be transient, we don't put the
- # gateway device in error status here.
+ except (nsx_exc.InvalidSecurityCertificate, api_exc.NsxApiException):
with excutils.save_and_reraise_exception():
- LOG.exception(_("Unable to update gateway device: %s on NSX "
- "backend."), neutron_id)
- super(NsxPluginV2, self).update_gateway_device(
- context, neutron_id, old_gateway_device_data)
+ self._rollback_gw_device(context, neutron_id,
+ gw_data=old_gateway_device_data)
except n_exc.NotFound:
# The gateway device was probably deleted in the backend.
# The DB change should be rolled back and the status must
# be put in error
with excutils.save_and_reraise_exception():
- LOG.exception(_("Unable to update gateway device: %s on NSX "
- "backend, as the gateway was not found on "
- "the NSX backend."), neutron_id)
- with context.session.begin(subtransactions=True):
- super(NsxPluginV2, self).update_gateway_device(
- context, neutron_id, old_gateway_device_data)
- query = self._model_query(
- context, networkgw_db.NetworkGatewayDevice).filter(
- networkgw_db.NetworkGatewayDevice.id == neutron_id)
- query.update({'status': networkgw_db.ERROR},
- synchronize_session=False)
+ self._rollback_gw_device(context, neutron_id,
+ gw_data=old_gateway_device_data,
+ new_status=networkgw_db.ERROR)
def get_gateway_device(self, context, device_id, fields=None):
# Get device from database
from neutron.db import db_base_plugin_v2
from neutron import manager
from neutron.plugins.vmware.api_client import exception as api_exc
+from neutron.plugins.vmware.common import exceptions as nsx_exc
from neutron.plugins.vmware.dbexts import networkgw_db
from neutron.plugins.vmware.extensions import networkgw
from neutron.plugins.vmware import nsxlib
l2gwlib, 'delete_gateway_device')
get_gw_dev_status_patcher = mock.patch.object(
l2gwlib, 'get_gateway_device_status')
- mock_create_gw_dev = create_gw_dev_patcher.start()
- mock_create_gw_dev.return_value = {'uuid': 'callejon'}
- update_gw_dev_patcher.start()
+ self.mock_create_gw_dev = create_gw_dev_patcher.start()
+ self.mock_create_gw_dev.return_value = {'uuid': 'callejon'}
+ self.mock_update_gw_dev = update_gw_dev_patcher.start()
delete_gw_dev_patcher.start()
self.mock_get_gw_dev_status = get_gw_dev_status_patcher.start()
super(TestNetworkGateway, self).test_create_gateway_device(
expected_status=networkgw_db.STATUS_DOWN)
+ def test_create_gateway_device_invalid_cert_returns_400(self):
+ self.mock_create_gw_dev.side_effect = (
+ nsx_exc.InvalidSecurityCertificate)
+ res = self._create_gateway_device(
+ 'json',
+ _uuid(),
+ connector_type='stt',
+ connector_ip='1.1.1.1',
+ client_certificate='invalid_certificate',
+ name='whatever')
+ self.assertEqual(res.status_int, 400)
+
def test_get_gateway_device(self):
self.mock_get_gw_dev_status.return_value = True
super(TestNetworkGateway, self).test_get_gateway_device(
super(TestNetworkGateway, self).test_update_gateway_device(
expected_status=networkgw_db.STATUS_DOWN)
+ def test_update_gateway_device_invalid_cert_returns_400(self):
+ with self._gateway_device(
+ name='whaterver',
+ connector_type='stt',
+ connector_ip='1.1.1.1',
+ client_certificate='iminvalidbutiitdoesnotmatter') as dev:
+ self.mock_update_gw_dev.side_effect = (
+ nsx_exc.InvalidSecurityCertificate)
+ res = self._update_gateway_device(
+ 'json',
+ dev[self.dev_resource]['id'],
+ client_certificate='invalid_certificate')
+ self.assertEqual(res.status_int, 400)
+
class TestNetworkGatewayPlugin(db_base_plugin_v2.NeutronDbPluginV2,
networkgw_db.NetworkGatewayMixin):