diff --git a/vmware_nsx/extension_drivers/dns_integration.py b/vmware_nsx/extension_drivers/dns_integration.py index 92d7811bf3..61de248f1a 100644 --- a/vmware_nsx/extension_drivers/dns_integration.py +++ b/vmware_nsx/extension_drivers/dns_integration.py @@ -83,7 +83,7 @@ class DNSExtensionDriver(driver_api.ExtensionDriver): if not request_data.get(dns.DNSNAME): return dns_name, is_dns_domain_default = self._get_request_dns_name( - request_data, db_data['network_id']) + request_data, db_data['network_id'], plugin_context) if is_dns_domain_default: return network = self._get_network(plugin_context, db_data['network_id']) @@ -145,10 +145,9 @@ class DNSExtensionDriver(driver_api.ExtensionDriver): return if dns_name is not None: dns_name, is_dns_domain_default = self._get_request_dns_name( - request_data, db_data['network_id']) + request_data, db_data['network_id'], plugin_context) if is_dns_domain_default: - self._extend_port_dict(plugin_context.session, db_data, - db_data, None) + self._extend_port_dict(db_data, db_data, None, plugin_context) return network = self._get_network(plugin_context, db_data['network_id']) dns_domain = network[dns.DNSDOMAIN] @@ -163,8 +162,7 @@ class DNSExtensionDriver(driver_api.ExtensionDriver): else: dns_data_db = self._update_dns_db(dns_name, dns_domain, db_data, plugin_context, has_fixed_ips) - self._extend_port_dict(plugin_context.session, db_data, db_data, - dns_data_db) + self._extend_port_dict(db_data, db_data, dns_data_db, plugin_context) def _process_only_dns_name_update(self, plugin_context, db_data, dns_name): dns_data_db = port_obj.PortDNS.get_object( @@ -200,31 +198,32 @@ class DNSExtensionDriver(driver_api.ExtensionDriver): response_data[dns.DNSDOMAIN] = db_data.dns_domain[dns.DNSDOMAIN] return response_data - def _get_dns_domain(self, network_id): + def _get_dns_domain(self, network_id, context=None): if not cfg.CONF.dns_domain: return '' if cfg.CONF.dns_domain.endswith('.'): return cfg.CONF.dns_domain return '%s.' % cfg.CONF.dns_domain - def _get_request_dns_name(self, port, network_id): - dns_domain = self._get_dns_domain(network_id) + def _get_request_dns_name(self, port, network_id, context): + dns_domain = self._get_dns_domain(network_id, context) if ((dns_domain and dns_domain != DNS_DOMAIN_DEFAULT)): return (port.get(dns.DNSNAME, ''), False) return ('', True) - def _get_request_dns_name_and_domain_name(self, dns_data_db, network_id): - dns_domain = self._get_dns_domain(network_id) + def _get_request_dns_name_and_domain_name(self, dns_data_db, + network_id, context): + dns_domain = self._get_dns_domain(network_id, context) dns_name = '' if ((dns_domain and dns_domain != DNS_DOMAIN_DEFAULT)): if dns_data_db: dns_name = dns_data_db.dns_name return dns_name, dns_domain - def _get_dns_names_for_port(self, ips, dns_data_db, network_id): + def _get_dns_names_for_port(self, ips, dns_data_db, network_id, context): dns_assignment = [] dns_name, dns_domain = self._get_request_dns_name_and_domain_name( - dns_data_db, network_id) + dns_data_db, network_id, context) for ip in ips: if dns_name: hostname = dns_name @@ -242,25 +241,26 @@ class DNSExtensionDriver(driver_api.ExtensionDriver): 'fqdn': fqdn}) return dns_assignment - def _get_dns_name_for_port_get(self, port, dns_data_db): + def _get_dns_name_for_port_get(self, port, dns_data_db, context): if port['fixed_ips']: return self._get_dns_names_for_port( - port['fixed_ips'], dns_data_db, port['network_id']) + port['fixed_ips'], dns_data_db, + port['network_id'], context) return [] - def _extend_port_dict(self, session, db_data, response_data, dns_data_db): + def _extend_port_dict(self, db_data, response_data, + dns_data_db, context=None): if not dns_data_db: response_data[dns.DNSNAME] = '' else: response_data[dns.DNSNAME] = dns_data_db[dns.DNSNAME] response_data['dns_assignment'] = self._get_dns_name_for_port_get( - db_data, dns_data_db) + db_data, dns_data_db, context) return response_data def extend_port_dict(self, session, db_data, response_data): dns_data_db = db_data.dns - return self._extend_port_dict(session, db_data, response_data, - dns_data_db) + return self._extend_port_dict(db_data, response_data, dns_data_db) def _get_network(self, context, network_id): plugin = directory.get_plugin() @@ -287,18 +287,19 @@ class DNSExtensionDriverNSXv3(DNSExtensionDriver): self._availability_zones = nsx_az.NsxV3AvailabilityZones() LOG.info("DNSExtensionDriverNSXv3 initialization complete") - def _get_network_az(self, network_id): - context = n_context.get_admin_context() + def _get_network_az(self, network_id, context): + if not context: + context = n_context.get_admin_context() network = self._get_network(context, network_id) if az_ext.AZ_HINTS in network and network[az_ext.AZ_HINTS]: az_name = network[az_ext.AZ_HINTS][0] return self._availability_zones.get_availability_zone(az_name) return self._availability_zones.get_default_availability_zone() - def _get_dns_domain(self, network_id): + def _get_dns_domain(self, network_id, context=None): # try to get the dns-domain from the specific availability zone # of this network - az = self._get_network_az(network_id) + az = self._get_network_az(network_id, context) if az.dns_domain: dns_domain = az.dns_domain elif cfg.CONF.nsx_v3.dns_domain: diff --git a/vmware_nsx/plugins/nsx_v/plugin.py b/vmware_nsx/plugins/nsx_v/plugin.py index 9931ec7936..3006be8522 100644 --- a/vmware_nsx/plugins/nsx_v/plugin.py +++ b/vmware_nsx/plugins/nsx_v/plugin.py @@ -1359,16 +1359,17 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, 'Reason: %(e)s', {'port_id': port_id, 'e': e}) - self._process_l3_delete(context, id) - # We would first delete subnet db if the backend dhcp service is - # deleted in case of entering delete_subnet logic and retrying - # to delete backend dhcp service again. - if is_dhcp_backend_deleted: - subnets = self._get_subnets_by_network(context, id) - for subnet in subnets: - super(NsxVPluginV2, self).delete_subnet( - context, subnet['id']) - super(NsxVPluginV2, self).delete_network(context, id) + with db_api.context_manager.writer.using(context): + self._process_l3_delete(context, id) + # We would first delete subnet db if the backend dhcp service is + # deleted in case of entering delete_subnet logic and retrying + # to delete backend dhcp service again. + if is_dhcp_backend_deleted: + subnets = self._get_subnets_by_network(context, id) + for subnet in subnets: + super(NsxVPluginV2, self).delete_subnet( + context, subnet['id']) + super(NsxVPluginV2, self).delete_network(context, id) # Do not delete a predefined port group that was attached to # an external network @@ -1679,6 +1680,8 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, with db_api.context_manager.writer.using(context): # First we allocate port in neutron database neutron_db = super(NsxVPluginV2, self).create_port(context, port) + self._extension_manager.process_create_port( + context, port_data, neutron_db) # Port port-security is decided by the port-security state on the # network it belongs to, unless specifically specified here if validators.is_attr_set(port_data.get(psec.PORTSECURITY)): @@ -1739,20 +1742,6 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, self._process_port_create_extra_dhcp_opts( context, port_data, dhcp_opts) - # Invoking the manager callback under transaction fails so here - # we do it outside. If this fails we will blow away the port - try: - with db_api.context_manager.writer.using(context): - self._extension_manager.process_create_port( - context, port_data, neutron_db) - except Exception as e: - with excutils.save_and_reraise_exception(): - LOG.error('Failed to create port %(id)s. ' - 'Exception: %(e)s', - {'id': neutron_db['id'], 'e': e}) - # Revert what we have created and raise the exception - self.delete_port(context, port_data['id']) - try: # Configure NSX - this should not be done in the DB transaction # Configure the DHCP Edge service diff --git a/vmware_nsx/plugins/nsx_v3/plugin.py b/vmware_nsx/plugins/nsx_v3/plugin.py index 106f7e41c9..298d7aa05a 100644 --- a/vmware_nsx/plugins/nsx_v3/plugin.py +++ b/vmware_nsx/plugins/nsx_v3/plugin.py @@ -884,9 +884,10 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, first_try = True while True: try: - self._process_l3_delete(context, network_id) - return super(NsxV3Plugin, self).delete_network( - context, network_id) + with db_api.context_manager.writer.using(context): + self._process_l3_delete(context, network_id) + return super(NsxV3Plugin, self).delete_network( + context, network_id) except n_exc.NetworkInUse: # There is a race condition in delete_network() that we need # to work around here. delete_network() issues a query to @@ -2035,6 +2036,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, port_data, port_data.get('device_owner')) neutron_db = super(NsxV3Plugin, self).create_port(context, port) + self._extension_manager.process_create_port( + context, port_data, neutron_db) port["port"].update(neutron_db) (is_psec_on, has_ip) = self._create_port_preprocess_security( @@ -2068,19 +2071,6 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, # ATTR_NOT_SPECIFIED port_data.pop(mac_ext.MAC_LEARNING) - # Invoking the manager callback under transaction fails so here - # we do it outside. If this fails we will blow away the port - try: - with db_api.context_manager.writer.using(context): - self._extension_manager.process_create_port( - context, port_data, neutron_db) - except Exception as e: - with excutils.save_and_reraise_exception(): - LOG.error('Failed to create port %(id)s. ' - 'Exception: %(e)s', - {'id': neutron_db['id'], 'e': e}) - self._cleanup_port(context, neutron_db['id'], None) - # Operations to backend should be done outside of DB transaction. # NOTE(arosen): ports on external networks are nat rules and do # not result in ports on the backend.