NSX: do not block init with security group logging configuration

Ensure that service is not blocked when updating the security group
logging configuration

Change-Id: I76eeeb351a9a7dfb8ded5aa47ae4f29d91fa3939
This commit is contained in:
Gary Kotton 2016-04-03 01:25:35 -07:00
parent 026a656893
commit 9089b5bc8d
3 changed files with 76 additions and 40 deletions

View File

@ -13,12 +13,15 @@
# License for the specific language governing permissions and limitations
# under the License.
import functools
import hashlib
import eventlet
from neutron.api.v2 import attributes
from neutron import version
from neutron_lib import exceptions
from oslo_config import cfg
from oslo_context import context as common_context
from oslo_log import log
import retrying
import six
@ -257,3 +260,26 @@ def is_ipv4_ip_address(addr):
if not _valid_part(ip_part):
return False
return True
def spawn_n(func, *args, **kwargs):
"""Passthrough method for eventlet.spawn_n.
This utility exists so that it can be stubbed for testing without
interfering with the service spawns.
It will also grab the context from the threadlocal store and add it to
the store on the new thread. This allows for continuity in logging the
context when using this method to spawn a new thread.
"""
_context = common_context.get_current()
@functools.wraps(func)
def context_wrapper(*args, **kwargs):
# NOTE: If update_store is not called after spawn_n it won't be
# available for the logger to pull from threadlocal storage.
if _context is not None:
_context.update_store()
func(*args, **kwargs)
eventlet.spawn_n(context_wrapper, *args, **kwargs)

View File

@ -291,35 +291,39 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
def _process_security_groups_rules_logging(self):
with locking.LockManager.get_lock('nsx-dfw-section',
lock_file_prefix='dfw-section',
external=True):
context = n_context.get_admin_context()
log_all_rules = cfg.CONF.nsxv.log_security_groups_allowed_traffic
def process_security_groups_rules_logging(*args, **kwargs):
with locking.LockManager.get_lock('nsx-dfw-section',
lock_file_prefix='dfw-section'):
context = n_context.get_admin_context()
log_allowed = cfg.CONF.nsxv.log_security_groups_allowed_traffic
# If the section/sg is already logged, then no action is
# required.
for sg in [sg for sg in self.get_security_groups(context)
if sg[sg_logging.LOGGING] is False]:
section_uri = self._get_section_uri(context.session, sg['id'])
if section_uri is None:
continue
# If the section/sg is already logged, then no action is
# required.
for sg in [sg for sg in self.get_security_groups(context)
if sg[sg_logging.LOGGING] is False]:
section_uri = self._get_section_uri(context.session,
sg['id'])
if section_uri is None:
continue
# Section/sg is not logged, update rules logging according to
# the 'log_security_groups_allowed_traffic' config option.
try:
h, c = self.nsx_v.vcns.get_section(section_uri)
section = self.nsx_sg_utils.parse_section(c)
section_needs_update = (
self.nsx_sg_utils.set_rules_logged_option(
section, log_all_rules))
if section_needs_update:
self.nsx_v.vcns.update_section(
section_uri,
self.nsx_sg_utils.to_xml_string(section), h)
except Exception as exc:
LOG.error(_LE('Unable to update section for logging. %s'),
exc)
# Section/sg is not logged, update rules logging according
# to the 'log_security_groups_allowed_traffic' config
# option.
try:
h, c = self.nsx_v.vcns.get_section(section_uri)
section = self.nsx_sg_utils.parse_section(c)
section_needs_update = (
self.nsx_sg_utils.set_rules_logged_option(
section, log_allowed))
if section_needs_update:
self.nsx_v.vcns.update_section(
section_uri,
self.nsx_sg_utils.to_xml_string(section), h)
except Exception as exc:
LOG.error(_LE('Unable to update section for logging. '
'%s'), exc)
c_utils.spawn_n(process_security_groups_rules_logging)
def _create_dhcp_static_binding(self, context, neutron_port_db):

View File

@ -272,19 +272,25 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
return self._get_port_security_profile()
def _process_security_group_logging(self):
context = q_context.get_admin_context()
log_all_rules = cfg.CONF.nsx_v3.log_security_groups_allowed_traffic
secgroups = self.get_security_groups(context,
fields=['id', sg_logging.LOGGING])
for sg in [sg for sg in secgroups if sg[sg_logging.LOGGING] is False]:
_, section_id = security.get_sg_mappings(context.session, sg['id'])
try:
security.set_firewall_rule_logging_for_section(
section_id, logging=log_all_rules)
except nsx_exc.ManagerError:
with excutils.save_and_reraise_exception():
LOG.error(_LE("Failed to update firewall rule logging for "
"rule in section %s"), section_id)
def process_security_group_logging(*args, **kwargs):
context = q_context.get_admin_context()
log_all_rules = cfg.CONF.nsx_v3.log_security_groups_allowed_traffic
secgroups = self.get_security_groups(context,
fields=['id',
sg_logging.LOGGING])
for sg in [sg for sg in secgroups
if sg[sg_logging.LOGGING] is False]:
_, section_id = security.get_sg_mappings(context.session,
sg['id'])
try:
security.set_firewall_rule_logging_for_section(
section_id, logging=log_all_rules)
except nsx_exc.ManagerError:
with excutils.save_and_reraise_exception():
LOG.error(_LE("Failed to update firewall rule logging "
"for rule in section %s"), section_id)
utils.spawn_n(process_security_group_logging)
def _init_nsgroup_manager_and_default_section_rules(self):
with locking.LockManager.get_lock('nsxv3_nsgroup_manager_init'):