Apply default firewall group for new VM ports

The default fwg will be applied to all new VM ports within
a project if option auto_association_default_firewall_group
is enabled. This provides a way for a tenant network admin
to define a tenant wide firewall policy that applies to all
new VM ports.

Co-Authored-By: Nguyen Phuong An <AnNP@vn.fujitsu.com>

Partial-Implements: blueprint fwaas-api-2.0
Change-Id: I9e897444cd63e44c3274cdc9efedb35f8b325d1f
This commit is contained in:
Yushiro FURUKAWA 2017-06-19 00:51:43 +09:00
parent 1272229d0b
commit 816dce17e1
4 changed files with 94 additions and 0 deletions

View File

@ -1100,3 +1100,18 @@ class Firewall_db_mixin_v2(fw_ext.Firewallv2PluginBase, base_db.CommonDbMixin):
if fwg_port_binding:
fwg_id = fwg_port_binding['firewall_group_id']
return self._make_firewall_group_dict_with_rules(context, fwg_id)
def _get_default_fwg(self, context, project_id):
query = self._model_query(context, DefaultFirewallGroup)
def_fwg_id = query.filter_by(
project_id=project_id).one().firewall_group_id
return self._get_firewall_group(context, def_fwg_id)
def set_port_for_default_firewall_group(self, context, port, project_id):
with context.session.begin(subtransactions=True):
def_fwg_db = self._get_default_fwg(context, project_id)
new_ports = [p.port_id for p in def_fwg_db['ports']] + [port]
fwg_ports = {'ports': new_ports}
self._set_ports_for_firewall_group(context, def_fwg_db, fwg_ports)
return self._make_firewall_group_dict_with_rules(
context, def_fwg_db['id'])

View File

@ -17,6 +17,9 @@ from neutron.db import servicetype_db as st_db
from neutron.services import provider_configuration as provider_conf
from neutron_lib.api.definitions import firewall_v2
from neutron_lib.api.definitions import portbindings as pb_def
from neutron_lib.callbacks import events
from neutron_lib.callbacks import registry
from neutron_lib.callbacks import resources
from neutron_lib import constants as nl_constants
from neutron_lib import context as neutron_context
from neutron_lib.exceptions import firewall_v2 as f_exc
@ -31,6 +34,14 @@ from neutron_fwaas.db.firewall.v2 import firewall_db_v2
LOG = logging.getLogger(__name__)
FW_V2_OPTS = [
cfg.BoolOpt(
'auto_associate_default_firewall_group',
default=False,
help=_("Apply default fwg to all new VM ports within a project")),
]
cfg.CONF.register_opts(FW_V2_OPTS, 'fwaas')
def add_provider_configuration(type_manager, service_type):
type_manager.add_provider_configuration(
@ -150,6 +161,7 @@ class FirewallCallbacks(object):
ctx, kwargs.get('port_id'))
@registry.has_registry_receivers
class FirewallPluginV2(
firewall_db_v2.Firewall_db_mixin_v2):
"""Implementation of the Neutron Firewall Service Plugin.
@ -173,6 +185,10 @@ class FirewallPluginV2(
cfg.CONF.host
)
self.apply_default_fwg = (
cfg.CONF.fwaas.auto_associate_default_firewall_group
)
@property
def _core_plugin(self):
return directory.get_plugin()
@ -284,6 +300,23 @@ class FirewallPluginV2(
"""Returns an ID of project for specified port_id. """
return self._core_plugin.get_port(context, port_id)['project_id']
@registry.receives(resources.PORT, [events.AFTER_CREATE])
def handle_create_port_event(self, resource, event, trigger, **kwargs):
if not self.apply_default_fwg:
return
context = kwargs['context']
port_id = kwargs['port']['id']
project_id = kwargs['port']['project_id']
fwg_with_rules = self.set_port_for_default_firewall_group(
context, port_id, project_id)
fwg_with_rules['add-port-ids'] = port_id
fwg_with_rules['del-ports-ids'] = []
fwg_with_rules['port_details'] = self._get_fwg_port_details(
context, port_id)
self.agent_rpc.update_firewall_group(context, fwg_with_rules)
def create_firewall_group(self, context, firewall_group):
LOG.debug("create_firewall_group() called")
fwgrp = firewall_group['firewall_group']

View File

@ -773,3 +773,35 @@ class TestFirewallPluginBasev2(TestFirewallRouterPortBase,
r['router']['id'],
s2['subnet']['id'],
None)
class TestEnabledAutomaticAssociation(TestFirewallPluginBasev2):
def setUp(self):
# set auto association fwg
cfg.CONF.set_override(
'auto_associate_default_firewall_group', True, 'fwaas')
super(TestEnabledAutomaticAssociation, self).setUp()
self.agent_rpc = self.plugin.agent_rpc
def test_enabled_auto_association_fwg(self):
fwg_with_rule = {'id': 'fake_id',
'name': 'default'}
self.plugin.set_port_for_default_firewall_group = \
mock.Mock(return_value=fwg_with_rule)
self.plugin._get_fwg_port_details = mock.Mock()
self.agent_rpc.update_firewall_group = mock.Mock()
m_context = mock.ANY
kwargs = {
"context": m_context,
"port": {"id": "fake_port",
"project_id": "fake_project"}
}
self.plugin.handle_create_port_event(
"PORT", "after_create", "test_plugin", **kwargs)
self.plugin.set_port_for_default_firewall_group.\
assert_called_once_with(m_context,
kwargs['port']['id'],
kwargs['port']['project_id'])
self.agent_rpc.update_firewall_group.assert_called_once_with(
m_context, fwg_with_rule)

View File

@ -0,0 +1,14 @@
---
prelude: >
Associating default firewall group for new VM ports within a project
automatically.
features:
- |
The default firewall group won't be applied to all new VM ports as default.
However, if option ``auto_associate_default_firewall_group`` is enabled in
neutron_fwaas.conf like:
[fwaas]
auto_associate_default_firewall_group = True
Then, the default firewall group will be applied to all new VM ports.