Add support for firewall driver configuration

Neutron has supported use of a native openvswitch firewall driver
for a few releases; OpenStack Mitaka on Ubuntu 16.04 has the
required kernel and openvswitch versions to support this feature.

Add a new firewall-driver configuration option to support use
of the openvswitch native firewall; the default remains as the
iptables_hybrid driver, and users can switch to the openvswitch
driver if they are deployed on Ubuntu Xenial or later.

Change-Id: I4c228c5cbbff7f9673c1028ee4b075edba1fdc13
Closes-Bug: 1681890
This commit is contained in:
James Page 2017-04-27 11:32:02 +01:00
parent dd7332386a
commit f22e6e9d1e
4 changed files with 87 additions and 1 deletions

View File

@ -96,6 +96,13 @@ options:
<physical_network> specifying physical_network names usable for VLAN
provider and tenant networks, as well as ranges of VLAN tags on each
available for allocation to tenant networks.
firewall-driver:
type: string
default:
description: |
Firewall driver to use to support use of security groups with
instances; valid values include iptables_hybrid (default) and
openvswitch (>= Mitaka on Ubuntu 16.04 or later).
# Network configuration options
# by default all access is over 'private-address'
os-data-network:

View File

@ -24,6 +24,10 @@ from charmhelpers.core.hookenv import (
unit_get,
network_get_primary_address,
)
from charmhelpers.core.host import (
CompareHostReleases,
lsb_release,
)
from charmhelpers.contrib.openstack import context
from charmhelpers.contrib.openstack.utils import get_host_ip
from charmhelpers.contrib.network.ip import get_address_in_network
@ -34,6 +38,31 @@ from charmhelpers.contrib.openstack.context import (
)
from charmhelpers.core.unitdata import kv
IPTABLES_HYBRID = 'iptables_hybrid'
OPENVSWITCH = 'openvswitch'
VALID_FIREWALL_DRIVERS = (IPTABLES_HYBRID, OPENVSWITCH)
def _get_firewall_driver():
'''
Determine the firewall driver to use based on configuration,
OpenStack and Ubuntu releases.
@returns str: firewall driver to use for OpenvSwitch
'''
driver = config('firewall-driver') or IPTABLES_HYBRID
release = lsb_release()['DISTRIB_CODENAME']
if driver not in VALID_FIREWALL_DRIVERS:
return IPTABLES_HYBRID
if (driver == OPENVSWITCH and
CompareHostReleases(release) < 'xenial'):
# NOTE(jamespage): Switch back to iptables_hybrid for
# Ubuntu releases prior to Xenial due
# to requirements for Linux >= 4.4 and
# Open vSwitch >= 2.5
return IPTABLES_HYBRID
return driver
class OVSPluginContext(context.NeutronContext):
interfaces = []
@ -117,6 +146,8 @@ class OVSPluginContext(context.NeutronContext):
if vlan_ranges:
ovs_ctxt['vlan_ranges'] = ','.join(vlan_ranges.split())
ovs_ctxt['firewall_driver'] = _get_firewall_driver()
return ovs_ctxt

View File

@ -24,7 +24,7 @@ veth_mtu = {{ veth_mtu }}
[securitygroup]
{% if neutron_security_groups and not enable_dpdk -%}
enable_security_group = True
firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver
firewall_driver = {{ firewall_driver }}
{% else -%}
enable_security_group = False
{% endif -%}

View File

@ -18,6 +18,14 @@ from mock import patch, Mock
import neutron_ovs_context as context
import charmhelpers
_LSB_RELEASE_XENIAL = {
'DISTRIB_CODENAME': 'xenial',
}
_LSB_RELEASE_TRUSTY = {
'DISTRIB_CODENAME': 'trusty',
}
TO_PATCH = [
'config',
'unit_get',
@ -28,6 +36,7 @@ TO_PATCH = [
'relation_ids',
'relation_get',
'related_units',
'lsb_release',
]
@ -48,6 +57,7 @@ class OVSPluginContextTest(CharmTestCase):
self.test_config.set('verbose', True)
self.test_config.set('use-syslog', True)
self.network_get_primary_address.side_effect = NotImplementedError
self.lsb_release.return_value = _LSB_RELEASE_XENIAL
def tearDown(self):
super(OVSPluginContextTest, self).tearDown()
@ -152,6 +162,7 @@ class OVSPluginContextTest(CharmTestCase):
'config': 'neutron.randomconfig',
'use_syslog': True,
'enable_dpdk': False,
'firewall_driver': 'iptables_hybrid',
'network_manager': 'neutron',
'debug': True,
'core_plugin': 'neutron.randomdriver',
@ -219,6 +230,7 @@ class OVSPluginContextTest(CharmTestCase):
'config': 'neutron.randomconfig',
'use_syslog': True,
'enable_dpdk': False,
'firewall_driver': 'iptables_hybrid',
'network_manager': 'neutron',
'debug': True,
'core_plugin': 'neutron.randomdriver',
@ -580,3 +592,39 @@ class TestRemoteRestartContext(CharmTestCase):
context.RemoteRestartContext()(),
{'restart_trigger_neutron': 'neutron-uuid'}
)
class TestFirewallDriver(CharmTestCase):
TO_PATCH = [
'config',
'lsb_release',
]
def setUp(self):
super(TestFirewallDriver, self).setUp(context,
self.TO_PATCH)
self.config.side_effect = self.test_config.get
def test_get_firewall_driver_xenial_unset(self):
self.lsb_release.return_value = _LSB_RELEASE_XENIAL
self.assertEqual(context._get_firewall_driver(),
context.IPTABLES_HYBRID)
def test_get_firewall_driver_xenial_openvswitch(self):
self.test_config.set('firewall-driver', 'openvswitch')
self.lsb_release.return_value = _LSB_RELEASE_XENIAL
self.assertEqual(context._get_firewall_driver(),
context.OPENVSWITCH)
def test_get_firewall_driver_xenial_invalid(self):
self.test_config.set('firewall-driver', 'foobar')
self.lsb_release.return_value = _LSB_RELEASE_XENIAL
self.assertEqual(context._get_firewall_driver(),
context.IPTABLES_HYBRID)
def test_get_firewall_driver_trusty_openvswitch(self):
self.test_config.set('firewall-driver', 'openvswitch')
self.lsb_release.return_value = _LSB_RELEASE_TRUSTY
self.assertEqual(context._get_firewall_driver(),
context.IPTABLES_HYBRID)