Introducing security group container

This change adds an NSXv security-group that contains all NSXv
security-groups created in Neutron, the security-group container will
aid with applying firewall rules to all Neutron security-groups, such as
the "Block All" rule.

Change-Id: Ib83685f7db55cfa369a9144fcca831a3552725d9
Signed-off-by: Roey Chen <roeyc@vmware.com>
This commit is contained in:
Roey Chen 2015-02-09 07:44:27 -08:00
parent df784cce90
commit f4ecce9037
4 changed files with 46 additions and 4 deletions

View File

@ -127,6 +127,7 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
self.nsx_v)
# Ensure that edges do concurrency
self._ensure_lock_operations()
self.sg_container_id = self._create_security_group_container()
self._validate_config()
self._create_cluster_default_fw_rules()
@ -139,6 +140,17 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
nsx_v_md_proxy.NsxVMetadataProxyHandler(self)
if has_metadata_cfg else None)
def _create_security_group_container(self):
name = "OpenStack Security Group container"
container_id = self.nsx_v.vcns.get_security_group_id(name)
if not container_id:
description = ("OpenStack Security Group Container, "
"managed by Neutron nsx-v plugin.")
container = {"securitygroup": {"name": name,
"description": description}}
h, container_id = self.nsx_v.vcns.create_security_group(container)
return container_id
def _create_cluster_default_fw_rules(self):
# default cluster rules
rules = [{'name': 'Default DHCP rule for OS Security Groups',
@ -148,10 +160,7 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
{'name': 'ICMPv6 neighbor protocol for Security Groups',
'action': 'allow',
'services': [('58', None, '135', None),
('58', None, '136', None)]},
{'name': 'Block All',
'action': 'deny',
'services': []}]
('58', None, '136', None)]}]
rule_list = []
for cluster_moid in cfg.CONF.nsxv.cluster_moid:
@ -161,6 +170,10 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
'ClusterComputeResource', services=rule['services'])
rule_list.append(rule_config)
block_rule = self.nsx_sg_utils.get_rule_config(
self.sg_container_id, 'Block All', 'deny')
rule_list.append(block_rule)
if rule_list:
section_name = 'OS Cluster Security Group section'
section_id = self.nsx_v.vcns.get_section_id(section_name)
@ -1754,6 +1767,10 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
nsxv_db.add_neutron_nsx_rule_mapping(
context.session, _neutron_id, _nsx_id)
# Add this Security Group to the Security Groups container
self._add_member_to_security_group(self.sg_container_id,
nsx_sg_id)
except Exception:
with excutils.save_and_reraise_exception():
# Delete the nsx rule section

View File

@ -459,6 +459,15 @@ class Vcns(object):
uri = '%s/%s?force=true' % (SECURITYGROUP_PREFIX, securitygroup_id)
return self.do_request(HTTP_DELETE, uri, format='xml', decode=False)
def get_security_group_id(self, sg_name):
"""Returns NSXv security group id which match the given name."""
uri = '%s/scope/globalroot-0' % SECURITYGROUP_PREFIX
h, c = self.do_request(HTTP_GET, uri, format='xml', decode=False)
root = et.fromstring(c)
for sg in root.iter('securitygroup'):
if sg.find('name').text == sg_name:
return sg.find('objectId').text
def create_section(self, type, request):
"""Creates a layer 3 or layer 2 section in nsx rule table.

View File

@ -1480,6 +1480,7 @@ class NsxVTestSecurityGroup(ext_sg.TestSecurityGroups,
self._delete('ports', port['id'])
def test_vnic_security_group_membership(self):
p = manager.NeutronManager.get_plugin()
self.fc2.add_member_to_security_group = (
mock.Mock().add_member_to_security_group)
self.fc2.remove_member_from_security_group = (
@ -1491,6 +1492,9 @@ class NsxVTestSecurityGroup(ext_sg.TestSecurityGroups,
vnic_id = '%s.%03d' % (device_id, port_index)
with self.port(device_id=device_id,
device_owner='compute:None') as port:
(self.fc2.add_member_to_security_group
.assert_called_once_with(p.sg_container_id, nsx_sg_id))
self.fc2.add_member_to_security_group.reset_mock()
data = {'port': {'vnic_index': port_index}}
self.new_update_request('ports', data,
port['port']['id']).get_response(self.api)

View File

@ -824,6 +824,11 @@ class FakeVcns(object):
status, response = 200, ''
return ({'status': status}, response)
def get_security_group_id(self, sg_name):
for k, v in self._securitygroups.items():
if k not in ('ids', 'names') and v['name'] == sg_name:
return k
def create_section(self, type, request):
section = ET.fromstring(request)
section_name = section.attrib.get('name')
@ -910,6 +915,13 @@ class FakeVcns(object):
'etag': self._sections[section_id]['etag']}
return (headers, response)
def get_section_id(self, section_name):
self._sections = {'section_ids': 0, 'rule_ids': 0, 'names': set()}
for k, v in self._sections.items():
if (k not in ('section_ids', 'rule_ids', 'names')
and v['name'] == section_name):
return k
def remove_rule_from_section(self, section_uri, rule_id):
section_id = self._get_section_id_from_uri(section_uri)
if section_id not in self._sections: