def create_l2_gateway_connection_postcommit(self, context, gw_connection): """Create a L2 gateway connection.""" l2gw_id = gw_connection.get(l2gw_const.L2GATEWAY_ID) network_id = gw_connection.get(l2gw_const.NETWORK_ID) device_name = self._get_bridge_cluster(context, l2gw_id) seg_id = self._get_conn_seg_id(context, gw_connection) self._validate_segment_id(seg_id) tenant_id = gw_connection['tenant_id'] if context.is_admin and not tenant_id: tenant_id = context.tenant_id gw_connection['tenant_id'] = tenant_id try: tags = self._core_plugin.nsxlib.build_v3_tags_payload( gw_connection, resource_type='os-neutron-l2gw-id', project_name=context.tenant_name) bridge_endpoint = self._core_plugin.nsxlib.bridge_endpoint.create( device_name=device_name, seg_id=seg_id, tags=tags) except nsxlib_exc.ManagerError as e: LOG.exception( "Unable to create bridge endpoint, rolling back " "changes on neutron. Exception is %s", e) raise l2gw_exc.L2GatewayServiceDriverError( method='create_l2_gateway_connection_postcommit') #TODO(abhiraut): Consider specifying the name of the port # Create a logical port and connect it to the bridge endpoint. port_dict = { 'port': { 'tenant_id': tenant_id, 'network_id': network_id, 'mac_address': constants.ATTR_NOT_SPECIFIED, 'admin_state_up': True, 'fixed_ips': [], 'device_id': bridge_endpoint['id'], 'device_owner': nsx_constants.BRIDGE_ENDPOINT, 'name': '', } } try: #TODO(abhiraut): Consider adding UT for port check once UTs are # refactored port = self._core_plugin.create_port(context, port_dict, l2gw_port_check=True) # Deallocate IP address from the port. for fixed_ip in port.get('fixed_ips', []): self._core_plugin._delete_ip_allocation( context, network_id, fixed_ip['subnet_id'], fixed_ip['ip_address']) LOG.debug("IP addresses deallocated on port %s", port['id']) except (nsxlib_exc.ManagerError, n_exc.NeutronException) as e: LOG.exception( "Unable to create L2 gateway port, " "rolling back changes on neutron: %s", e) self._core_plugin.nsxlib.bridge_endpoint.delete( bridge_endpoint['id']) raise l2gw_exc.L2GatewayServiceDriverError( method='create_l2_gateway_connection_postcommit') try: # Update neutron's database with the mappings. nsx_db.add_l2gw_connection_mapping( session=context.session, connection_id=gw_connection['id'], bridge_endpoint_id=bridge_endpoint['id'], port_id=port['id']) except db_exc.DBError: with excutils.save_and_reraise_exception(): LOG.exception("Unable to add L2 gateway connection " "mappings, rolling back changes on neutron") self._core_plugin.nsxlib.bridge_endpoint.delete( bridge_endpoint['id']) super(NsxV3Driver, self).delete_l2_gateway_connection( context, gw_connection['id']) return gw_connection
def create_l2_gateway_connection(self, context, l2_gateway_connection): """Create a L2 gateway connection.""" #TODO(abhiraut): Move backend logic in a separate method gw_connection = l2_gateway_connection.get(l2gw_const. CONNECTION_RESOURCE_NAME) network_id = gw_connection.get(l2gw_const.NETWORK_ID) self._validate_network(context, network_id) l2gw_connection = super( NsxV3Driver, self).create_l2_gateway_connection( context, l2_gateway_connection) l2gw_id = gw_connection.get(l2gw_const.L2GATEWAY_ID) devices = self._get_l2_gateway_devices(context, l2gw_id) # In NSXv3, there will be only one device configured per L2 gateway. # The name of the device shall carry the backend bridge cluster's UUID. device_name = devices[0].get('device_name') # The seg-id will be provided either during gateway create or gateway # connection create. l2gateway_db_mixin makes sure that it is # configured one way or the other. seg_id = gw_connection.get(l2gw_const.SEG_ID) if not seg_id: # Seg-id was not passed as part of connection-create. Retrieve # seg-id from L2 gateway's interface. interface = self._get_l2_gw_interfaces(context, devices[0]['id']) seg_id = interface[0].get(l2gw_const.SEG_ID) self._validate_segment_id(seg_id) try: tags = nsx_utils.build_v3_tags_payload( gw_connection, resource_type='os-neutron-l2gw-id', project_name=context.tenant_name) bridge_endpoint = nsxlib.create_bridge_endpoint( device_name=device_name, seg_id=seg_id, tags=tags) except nsx_exc.ManagerError: LOG.exception(_LE("Unable to update NSX backend, rolling back " "changes on neutron")) with excutils.save_and_reraise_exception(): super(NsxV3Driver, self).delete_l2_gateway_connection(context, l2gw_connection['id']) # Create a logical port and connect it to the bridge endpoint. tenant_id = gw_connection['tenant_id'] if context.is_admin and not tenant_id: tenant_id = context.tenant_id #TODO(abhiraut): Consider specifying the name of the port port_dict = {'port': { 'tenant_id': tenant_id, 'network_id': network_id, 'mac_address': constants.ATTR_NOT_SPECIFIED, 'admin_state_up': True, 'fixed_ips': [], 'device_id': bridge_endpoint['id'], 'device_owner': nsx_constants.BRIDGE_ENDPOINT, 'name': '', }} try: #TODO(abhiraut): Consider adding UT for port check once UTs are # refactored port = self._core_plugin.create_port(context, port_dict, l2gw_port_check=True) # Deallocate IP address from the port. for fixed_ip in port.get('fixed_ips', []): self._core_plugin._delete_ip_allocation(context, network_id, fixed_ip['subnet_id'], fixed_ip['ip_address']) LOG.debug("IP addresses deallocated on port %s", port['id']) except (nsx_exc.ManagerError, n_exc.NeutronException): with excutils.save_and_reraise_exception(): LOG.exception(_LE("Unable to create L2 gateway port, " "rolling back changes on neutron")) nsxlib.delete_bridge_endpoint(bridge_endpoint['id']) super(NsxV3Driver, self).delete_l2_gateway_connection(context, l2gw_connection['id']) try: # Update neutron's database with the mappings. nsx_db.add_l2gw_connection_mapping( session=context.session, connection_id=l2gw_connection['id'], bridge_endpoint_id=bridge_endpoint['id'], port_id=port['id']) except db_exc.DBError: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Unable to add L2 gateway connection " "mappings, rolling back changes on neutron")) nsxlib.delete_bridge_endpoint(bridge_endpoint['id']) super(NsxV3Driver, self).delete_l2_gateway_connection(context, l2gw_connection['id']) return l2gw_connection
def create_l2_gateway_connection_postcommit(self, context, gw_connection): """Create a L2 gateway connection on the backend""" nsxlib = self._core_plugin.nsxlib l2gw_id = gw_connection.get(l2gw_const.L2GATEWAY_ID) network_id = gw_connection.get(l2gw_const.NETWORK_ID) device_name = self._get_bep(context, l2gw_id) interface_name, seg_id = self._get_conn_parameters( context, gw_connection) self._validate_segment_id(seg_id) tenant_id = gw_connection['tenant_id'] if context.is_admin and not tenant_id: tenant_id = context.tenant_id gw_connection['tenant_id'] = tenant_id try: tags = nsxlib.build_v3_tags_payload( gw_connection, resource_type='os-neutron-l2gw-id', project_name=context.tenant_name) bridge_endpoint = nsxlib.bridge_endpoint.create( device_name=device_name, vlan_transport_zone_id=interface_name, vlan_id=seg_id, tags=tags) except nsxlib_exc.ManagerError as e: LOG.exception("Unable to create bridge endpoint. " "Exception is %s", e) raise l2gw_exc.L2GatewayServiceDriverError( method='create_l2_gateway_connection_postcommit') port_dict = {'port': { 'name': 'l2gw-conn-%s-%s' % ( l2gw_id, seg_id), 'tenant_id': tenant_id, 'network_id': network_id, 'mac_address': constants.ATTR_NOT_SPECIFIED, 'admin_state_up': True, 'fixed_ips': [], 'device_id': bridge_endpoint['id'], 'device_owner': nsx_constants.BRIDGE_ENDPOINT}} try: #TODO(abhiraut): Consider adding UT for port check once UTs are # refactored port = self._core_plugin.create_port(context, port_dict, l2gw_port_check=True) # Deallocate IP address from the port. for fixed_ip in port.get('fixed_ips', []): self._core_plugin._delete_ip_allocation(context, network_id, fixed_ip['subnet_id'], fixed_ip['ip_address']) LOG.debug("IP addresses deallocated on port %s", port['id']) except (nsxlib_exc.ManagerError, n_exc.NeutronException) as e: with excutils.save_and_reraise_exception(): LOG.exception("Unable to create L2 gateway port, " "rolling back changes on backend: %s", e) self._core_plugin.nsxlib.bridge_endpoint.delete( bridge_endpoint['id']) super(NsxV3Driver, self).delete_l2_gateway_connection( context, gw_connection['id']) try: # Update neutron's database with the mappings. nsx_db.add_l2gw_connection_mapping( session=context.session, connection_id=gw_connection['id'], bridge_endpoint_id=bridge_endpoint['id'], port_id=port['id']) except db_exc.DBError: with excutils.save_and_reraise_exception(): LOG.exception("Unable to add L2 gateway connection " "mappings for %(conn_id)s on network " "%(net_id)s. rolling back changes.", {'conn_id': gw_connection['id'], 'net_id': network_id}) self._core_plugin.nsxlib.bridge_endpoint.delete( bridge_endpoint['id']) super(NsxV3Driver, self).delete_l2_gateway_connection( context, gw_connection['id']) return gw_connection