Deny the creation of L7Policies for HTTPS/TCP/UDP listeners

L7Policies are not compatible with non-TERMINATED_HTTPS/HTTP listeners
(i.e HTTPS/TCP/UDP listeners).
The Amphora driver should deny those invalid combinations.

Story: 2007911
Task: 40314

Change-Id: I0f1cac05ebea12a300feffb22fdfe546cf802b87
(cherry picked from commit 45b0a507a1)
(cherry picked from commit 4248e98acb)
This commit is contained in:
Gregory Thiemonge 2020-07-09 14:25:39 +02:00
parent 5b4604c75b
commit df1ecbda2c
5 changed files with 71 additions and 2 deletions

View File

@ -55,6 +55,11 @@ AMPHORA_SUPPORTED_PROTOCOLS = [
lib_consts.PROTOCOL_SCTP,
]
VALID_L7POLICY_LISTENER_PROTOCOLS = [
lib_consts.PROTOCOL_HTTP,
lib_consts.PROTOCOL_TERMINATED_HTTPS
]
class AmphoraProviderDriver(driver_base.ProviderDriver):
def __init__(self):
@ -339,6 +344,14 @@ class AmphoraProviderDriver(driver_base.ProviderDriver):
# L7 Policy
def l7policy_create(self, l7policy):
db_listener = self.repositories.listener.get(db_apis.get_session(),
id=l7policy.listener_id)
if db_listener.protocol not in VALID_L7POLICY_LISTENER_PROTOCOLS:
msg = ('%s protocol listeners do not support L7 policies' % (
db_listener.protocol))
raise exceptions.UnsupportedOptionError(
user_fault_string=msg,
operator_fault_string=msg)
payload = {consts.L7POLICY_ID: l7policy.l7policy_id}
self.client.cast({}, 'create_l7policy', **payload)

View File

@ -56,6 +56,11 @@ AMPHORA_SUPPORTED_PROTOCOLS = [
lib_consts.PROTOCOL_SCTP,
]
VALID_L7POLICY_LISTENER_PROTOCOLS = [
lib_consts.PROTOCOL_HTTP,
lib_consts.PROTOCOL_TERMINATED_HTTPS
]
class AmphoraProviderDriver(driver_base.ProviderDriver):
def __init__(self):
@ -362,6 +367,14 @@ class AmphoraProviderDriver(driver_base.ProviderDriver):
# L7 Policy
def l7policy_create(self, l7policy):
db_listener = self.repositories.listener.get(db_apis.get_session(),
id=l7policy.listener_id)
if db_listener.protocol not in VALID_L7POLICY_LISTENER_PROTOCOLS:
msg = ('%s protocol listeners do not support L7 policies' % (
db_listener.protocol))
raise exceptions.UnsupportedOptionError(
user_fault_string=msg,
operator_fault_string=msg)
payload = {consts.L7POLICY: l7policy.to_dict()}
self.client.cast({}, 'create_l7policy', **payload)

View File

@ -619,14 +619,32 @@ class TestAmphoraDriver(base.TestRpc):
mock_cast.assert_called_with({}, 'update_health_monitor', **payload)
# L7 Policy
@mock.patch('octavia.db.api.get_session')
@mock.patch('octavia.db.repositories.ListenerRepository.get')
@mock.patch('oslo_messaging.RPCClient.cast')
def test_l7policy_create(self, mock_cast):
def test_l7policy_create(self, mock_cast, mock_listener_get, mock_session):
mock_listener = mock.MagicMock()
mock_listener.protocol = consts.PROTOCOL_HTTP
mock_listener_get.return_value = mock_listener
provider_l7policy = driver_dm.L7Policy(
l7policy_id=self.sample_data.l7policy1_id)
self.amp_driver.l7policy_create(provider_l7policy)
payload = {consts.L7POLICY_ID: self.sample_data.l7policy1_id}
mock_cast.assert_called_with({}, 'create_l7policy', **payload)
@mock.patch('octavia.db.api.get_session')
@mock.patch('octavia.db.repositories.ListenerRepository.get')
def test_l7policy_create_invalid_listener_protocol(self, mock_listener_get,
mock_session):
mock_listener = mock.MagicMock()
mock_listener.protocol = consts.PROTOCOL_UDP
mock_listener_get.return_value = mock_listener
provider_l7policy = driver_dm.L7Policy(
l7policy_id=self.sample_data.l7policy1_id)
self.assertRaises(exceptions.UnsupportedOptionError,
self.amp_driver.l7policy_create,
provider_l7policy)
@mock.patch('oslo_messaging.RPCClient.cast')
def test_l7policy_delete(self, mock_cast):
provider_l7policy = driver_dm.L7Policy(

View File

@ -674,14 +674,32 @@ class TestAmphoraDriver(base.TestRpc):
mock_cast.assert_called_with({}, 'update_health_monitor', **payload)
# L7 Policy
@mock.patch('octavia.db.api.get_session')
@mock.patch('octavia.db.repositories.ListenerRepository.get')
@mock.patch('oslo_messaging.RPCClient.cast')
def test_l7policy_create(self, mock_cast):
def test_l7policy_create(self, mock_cast, mock_listener_get, mock_session):
mock_listener = mock.MagicMock()
mock_listener.protocol = consts.PROTOCOL_HTTP
mock_listener_get.return_value = mock_listener
provider_l7policy = driver_dm.L7Policy(
l7policy_id=self.sample_data.l7policy1_id)
self.amp_driver.l7policy_create(provider_l7policy)
payload = {consts.L7POLICY: provider_l7policy.to_dict()}
mock_cast.assert_called_with({}, 'create_l7policy', **payload)
@mock.patch('octavia.db.api.get_session')
@mock.patch('octavia.db.repositories.ListenerRepository.get')
def test_l7policy_create_invalid_listener_protocol(self, mock_listener_get,
mock_session):
mock_listener = mock.MagicMock()
mock_listener.protocol = consts.PROTOCOL_UDP
mock_listener_get.return_value = mock_listener
provider_l7policy = driver_dm.L7Policy(
l7policy_id=self.sample_data.l7policy1_id)
self.assertRaises(exceptions.UnsupportedOptionError,
self.amp_driver.l7policy_create,
provider_l7policy)
@mock.patch('oslo_messaging.RPCClient.cast')
def test_l7policy_delete(self, mock_cast):
provider_l7policy = driver_dm.L7Policy(

View File

@ -0,0 +1,7 @@
---
fixes:
- |
Validate that the creation of L7 policies is compatible with the protocol
of the listener in the Amphora driver. L7 policies are allowed for
Terminated HTTPS or HTTP protocol listeners, but not for HTTPS, TCP or UDP
protocols listeners.