Add NSGroup container and default firewall section for security-groups

Change-Id: I0ecaf0ce56bbcedbbe056b510285975f75ad9288
This commit is contained in:
Roey Chen 2015-08-28 17:16:08 -07:00
parent 78ba18f6d2
commit 7bb63f2f8b
4 changed files with 80 additions and 12 deletions

View File

@ -26,6 +26,9 @@ from vmware_nsx.neutron.plugins.vmware.nsxlib.v3 import client as nsclient
# firewall section types
LAYER3 = 'LAYER3'
INSERT_BEFORE = 'insert_before'
INSERT_BOTTOM = 'insert_bottom'
# firewall rule actions
ALLOW = 'ALLOW'
DROP = 'DROP'
@ -42,6 +45,7 @@ IPV6ADDRESS = 'IPv6Address'
IN = 'IN'
OUT = 'OUT'
IN_OUT = 'IN_OUT'
# NSServices resource types
L4_PORT_SET_NSSERVICE = 'L4PortSetNSService'
@ -55,6 +59,7 @@ ICMPV6 = 'ICMPv6'
IPV4 = 'IPV4'
IPV6 = 'IPV6'
IPV4_IPV6 = 'IPV4_IPV6'
def get_nsservice(resource_type, **properties):
@ -71,7 +76,7 @@ def create_nsgroup(display_name, description, tags):
def list_nsgroups():
return nsclient.get_resource('ns-groups')
return nsclient.get_resource('ns-groups').get('results', [])
@utils.retry_upon_exception_nsxv3(nsx_exc.StaleRevision)
@ -124,9 +129,12 @@ def _build_section(display_name, description, applied_tos, tags):
'tags': tags}
def create_empty_section(display_name, description, applied_tos, tags):
resource = 'firewall/sections'
def create_empty_section(display_name, description, applied_tos, tags,
operation=INSERT_BOTTOM, other_section=None):
resource = 'firewall/sections?operation=%s' % operation
body = _build_section(display_name, description, applied_tos, tags)
if other_section:
resource += '&id=%s' % other_section
return nsclient.create_resource(resource, body)
@ -148,7 +156,7 @@ def read_section(section_id):
def list_sections():
resource = 'firewall/sections'
return nsclient.get_resource(resource)
return nsclient.get_resource(resource).get('results', [])
def delete_section(section_id):
@ -167,8 +175,9 @@ def get_ip_cidr_reference(ip_cidr_block, ip_protocol):
'target_type': target_type}
def get_firewall_rule_dict(display_name, source, destination, direction,
ip_protocol, service, action):
def get_firewall_rule_dict(display_name, source=None, destination=None,
direction=IN_OUT, ip_protocol=IPV4_IPV6,
service=None, action=ALLOW):
return {'display_name': display_name,
'sources': [source] if source else [],
'destinations': [destination] if destination else [],

View File

@ -24,6 +24,10 @@ from vmware_nsx.neutron.plugins.vmware.dbexts import nsx_models
from vmware_nsx.neutron.plugins.vmware.nsxlib.v3 import dfw_api as firewall
NSGROUP_CONTAINER = 'NSGroup Container'
DEFAULT_SECTION = 'OS default section for security-groups'
def _get_l4_protocol_name(proto_num):
if proto_num == 6:
return firewall.TCP
@ -170,3 +174,48 @@ def update_lport_with_security_groups(context, lport_id, original, updated):
nsgroup_id, _ = get_sg_mappings(context.session, sg_id)
firewall.remove_nsgroup_member(
nsgroup_id, lport_id)
def init_nsgroup_container_and_default_section_rules():
# REVISIT(roeyc): Should handle Neutron active-active
# deployment scenario.
nsgroup_description = ('This NSGroup is necessary for OpenStack '
'integration, do not delete.')
section_description = ("This section is handled by OpenStack to contain "
"default rules on security-groups.")
nsgroup_id = _init_nsgroup_container(NSGROUP_CONTAINER,
nsgroup_description)
section_id = _init_default_section(
DEFAULT_SECTION, section_description, nsgroup_id)
return nsgroup_id, section_id
def _init_nsgroup_container(name, description):
nsgroups = firewall.list_nsgroups()
for nsg in nsgroups:
if nsg['display_name'] == name:
# NSGroup container exists and so should the OS default
# security-groups section.
break
else:
# Need to create the nsgroup container and the OS default
# security-groups section.
nsg = firewall.create_nsgroup(name, description, [])
return nsg['id']
def _init_default_section(name, description, nsgroup_id):
fw_sections = firewall.list_sections()
for section in fw_sections:
if section['display_name'] == name:
break
else:
section = firewall.create_empty_section(
name, description, [nsgroup_id], [])
# TODO(roeyc): Add aditional rules to allow IPV6 NDP.
block_rule = firewall.get_firewall_rule_dict(
'Block All', action=firewall.DROP)
firewall.add_rule_in_section(block_rule, section['id'])
return section['id']

View File

@ -94,6 +94,8 @@ class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
'security-group' in self.supported_extension_aliases}}
self.tier0_groups_dict = {}
self._setup_rpc()
self.nsgroup_container, self.default_section = (
security.init_nsgroup_container_and_default_section_rules())
def _setup_rpc(self):
self.topic = topics.PLUGIN
@ -645,8 +647,11 @@ class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
ns_group = firewall.create_nsgroup(
name, secgroup['description'], tags)
# security-group rules are located in a dedicated firewall section.
firewall_section = firewall.create_empty_section(
name, secgroup.get('description', ''), [ns_group['id']], tags)
firewall_section = (
firewall.create_empty_section(
name, secgroup.get('description', ''), [ns_group['id']],
tags, operation=firewall.INSERT_BEFORE,
other_section=self.default_section))
# REVISIT(roeyc): Idealy, at this point we need not be under an
# open db transactions, however, unittests fail if omitting
@ -680,6 +685,9 @@ class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
rules = security.create_firewall_rules(
context, firewall_section['id'], ns_group['id'], sg_rules)
security.save_sg_rule_mappings(context.session, rules['rules'])
firewall.add_nsgroup_member(self.nsgroup_container,
firewall.NSGROUP, ns_group['id'])
except nsx_exc.ManagerError:
with excutils.save_and_reraise_exception():
LOG.exception(_LE("Failed to create backend firewall rules "

View File

@ -33,8 +33,6 @@ class NsxPluginV3TestCase(test_plugin.NeutronDbPluginV2TestCase):
plugin=PLUGIN_NAME,
ext_mgr=None,
service_plugins=None):
super(NsxPluginV3TestCase, self).setUp(plugin=plugin,
ext_mgr=ext_mgr)
cfg.CONF.set_override('nsx_manager', '1.2.3.4', 'nsx_v3')
# Mock entire nsxlib methods as this is the best approach to perform
# white-box testing on the plugin class
@ -56,6 +54,9 @@ class NsxPluginV3TestCase(test_plugin.NeutronDbPluginV2TestCase):
firewall.nsclient.get_resource = nsx_v3_mocks.get_resource
firewall.nsclient.delete_resource = nsx_v3_mocks.delete_resource
super(NsxPluginV3TestCase, self).setUp(plugin=plugin,
ext_mgr=ext_mgr)
class TestNetworksV2(test_plugin.TestNetworksV2, NsxPluginV3TestCase):
pass
@ -70,8 +71,6 @@ class SecurityGroupsTestCase(ext_sg.SecurityGroupDBTestCase):
def setUp(self,
plugin=PLUGIN_NAME,
ext_mgr=None):
super(SecurityGroupsTestCase, self).setUp(plugin=PLUGIN_NAME,
ext_mgr=ext_mgr)
nsxlib.create_logical_switch = nsx_v3_mocks.create_logical_switch
nsxlib.create_logical_port = nsx_v3_mocks.create_logical_port
nsxlib.update_logical_port = nsx_v3_mocks.update_logical_port
@ -85,6 +84,9 @@ class SecurityGroupsTestCase(ext_sg.SecurityGroupDBTestCase):
firewall.nsclient.get_resource = nsx_v3_mocks.get_resource
firewall.nsclient.delete_resource = nsx_v3_mocks.delete_resource
super(SecurityGroupsTestCase, self).setUp(plugin=PLUGIN_NAME,
ext_mgr=ext_mgr)
class TestSecurityGroups(ext_sg.TestSecurityGroups, SecurityGroupsTestCase):
pass