diff --git a/vmware_nsx/common/config.py b/vmware_nsx/common/config.py index d5733e12ef..e66432c2de 100644 --- a/vmware_nsx/common/config.py +++ b/vmware_nsx/common/config.py @@ -232,6 +232,9 @@ nsx_v3_opts = [ help=_('Number of times a HTTP redirect should be followed.')), cfg.StrOpt('default_tier0_router_uuid', help=_("Default tier0 router identifier")), + cfg.IntOpt('number_of_nested_groups', + default=8, + help=_("The number of nested NSGroups to use.")), ] DEFAULT_STATUS_CHECK_INTERVAL = 2000 diff --git a/vmware_nsx/nsxlib/v3/security.py b/vmware_nsx/nsxlib/v3/security.py index 087b8a1a8f..34579f1722 100644 --- a/vmware_nsx/nsxlib/v3/security.py +++ b/vmware_nsx/nsxlib/v3/security.py @@ -21,6 +21,7 @@ NSX-V3 Plugin security integration module import uuid from neutron.db import securitygroups_db +from oslo_config import cfg from oslo_log import log from vmware_nsx._i18n import _, _LW @@ -32,9 +33,6 @@ from vmware_nsx.nsxlib.v3 import dfw_api as firewall LOG = log.getLogger(__name__) -# TODO(roeyc): Make this number configurable -NUM_OF_NESTED_GROUPS = 8 - DEFAULT_SECTION = 'OS Default Section for Neutron Security-Groups' DEFAULT_SECTION_TAG_NAME = 'neutron_default_dfw_section' @@ -212,7 +210,7 @@ def init_nsgroup_manager_and_default_section_rules(): section_description = ("This section is handled by OpenStack to contain " "default rules on security-groups.") - nsgroup_manager = NSGroupManager(NUM_OF_NESTED_GROUPS) + nsgroup_manager = NSGroupManager(cfg.CONF.nsx_v3.number_of_nested_groups) section_id = _init_default_section( DEFAULT_SECTION, section_description, nsgroup_manager.nested_groups) return nsgroup_manager, section_id @@ -274,8 +272,8 @@ class NSGroupManager(object): NESTED_GROUP_DESCRIPTION = ('OpenStack NSGroup. Do not delete.') def __init__(self, size): - self._size = size - self._nested_groups = self._init_nested_groups() + self._nested_groups = self._init_nested_groups(size) + self._size = len(self._nested_groups) @property def size(self): @@ -285,18 +283,27 @@ class NSGroupManager(object): def nested_groups(self): return self._nested_groups - def _init_nested_groups(self): + def _init_nested_groups(self, requested_size): # Construct the groups dict - # {0: ,.., n-1: } + size = requested_size nested_groups = { self._get_nested_group_index_from_name(nsgroup): nsgroup['id'] for nsgroup in firewall.list_nsgroups() if utils.is_internal_resource(nsgroup)} - absent_groups = set(range(self.size)) - set(nested_groups.keys()) + if nested_groups: + size = max(requested_size, max(nested_groups) + 1) + if size > requested_size: + LOG.warning(_LW("Lowering the value of " + "nsx_v3:number_of_nested_groups isn't " + "supported, '%s' nested-groups will be used."), + size) + + absent_groups = set(range(size)) - set(nested_groups.keys()) if absent_groups: LOG.warning( - _LW("Missing %(num_present)s Nested Groups, " + _LW("Found %(num_present)s Nested Groups, " "creating %(num_absent)s more."), {'num_present': len(nested_groups), 'num_absent': len(absent_groups)}) @@ -307,7 +314,8 @@ class NSGroupManager(object): return nested_groups def _get_nested_group_index_from_name(self, nested_group): - return int(nested_group['display_name'][-1]) - 1 + # The name format is "Nested Group " + return int(nested_group['display_name'].split()[-1]) - 1 def _create_nested_group(self, index): name_prefix = NSGroupManager.NESTED_GROUP_NAME @@ -327,7 +335,7 @@ class NSGroupManager(object): yield self.nested_groups[index] for i in range(1, self.size): - index = (index + i) % self.size + index = (index + 1) % self.size yield self.nested_groups[index] def add_nsgroup(self, nsgroup_id): diff --git a/vmware_nsx/tests/unit/extensions/test_securitygroup.py b/vmware_nsx/tests/unit/extensions/test_securitygroup.py index 5b5efcb3c2..34a833d8ef 100644 --- a/vmware_nsx/tests/unit/extensions/test_securitygroup.py +++ b/vmware_nsx/tests/unit/extensions/test_securitygroup.py @@ -214,3 +214,14 @@ class TestNSGroupManager(nsxlib_testcase.NsxLibTestCase): 2: NSG_IDS[3], 3: NSG_IDS[2]}, cont_manager.nested_groups) + + @_mock_create_and_list_nsgroups + def test_suggest_nested_group(self): + size = 5 + cont_manager = security.NSGroupManager(size) + # We expect that the first suggested index is 2 + expected_suggested_groups = NSG_IDS[2:5] + NSG_IDS[:2] + suggest_group = lambda: cont_manager._suggest_nested_group('fake-id') + with mock.patch.object(cont_manager, '_hash_uuid', return_value=7): + for i, suggested in enumerate(suggest_group()): + self.assertEqual(expected_suggested_groups[i], suggested)