Add ALPN protocol scenario tests
Depends-On: https://review.opendev.org/#/c/744520/ Change-Id: I4ae7a03d2248c970d7bcd3fe8a43a43ca48d5084
This commit is contained in:
parent
bb23855ce6
commit
f7718ef862
|
@ -66,6 +66,7 @@ DEFAULT_TLS_CONTAINER_REF = 'default_tls_container_ref'
|
||||||
SNI_CONTAINER_REFS = 'sni_container_refs'
|
SNI_CONTAINER_REFS = 'sni_container_refs'
|
||||||
DEFAULT_POOL_ID = 'default_pool_id'
|
DEFAULT_POOL_ID = 'default_pool_id'
|
||||||
L7_POLICIES = 'l7_policies'
|
L7_POLICIES = 'l7_policies'
|
||||||
|
ALPN_PROTOCOLS = 'alpn_protocols'
|
||||||
|
|
||||||
LB_ALGORITHM = 'lb_algorithm'
|
LB_ALGORITHM = 'lb_algorithm'
|
||||||
LB_ALGORITHM_ROUND_ROBIN = 'ROUND_ROBIN'
|
LB_ALGORITHM_ROUND_ROBIN = 'ROUND_ROBIN'
|
||||||
|
|
|
@ -41,6 +41,7 @@ class ListenerClient(base_client.BaseLBaaSClient):
|
||||||
sni_container_refs=Unset, client_authentication=Unset,
|
sni_container_refs=Unset, client_authentication=Unset,
|
||||||
client_ca_tls_container_ref=Unset,
|
client_ca_tls_container_ref=Unset,
|
||||||
client_crl_container_ref=Unset, allowed_cidrs=Unset,
|
client_crl_container_ref=Unset, allowed_cidrs=Unset,
|
||||||
|
alpn_protocols=Unset,
|
||||||
return_object_only=True):
|
return_object_only=True):
|
||||||
"""Create a listener.
|
"""Create a listener.
|
||||||
|
|
||||||
|
@ -89,6 +90,8 @@ class ListenerClient(base_client.BaseLBaaSClient):
|
||||||
revocation list file for
|
revocation list file for
|
||||||
TERMINATED_HTTPS listeners.
|
TERMINATED_HTTPS listeners.
|
||||||
:param allowed_cidrs: A list of IPv4 or IPv6 CIDRs.
|
:param allowed_cidrs: A list of IPv4 or IPv6 CIDRs.
|
||||||
|
:param alpn_protocols: A list of ALPN protocols for TERMINATED_HTTPS
|
||||||
|
listeners.
|
||||||
:param return_object_only: If True, the response returns the object
|
:param return_object_only: If True, the response returns the object
|
||||||
inside the root tag. False returns the full
|
inside the root tag. False returns the full
|
||||||
response from the API.
|
response from the API.
|
||||||
|
@ -215,6 +218,7 @@ class ListenerClient(base_client.BaseLBaaSClient):
|
||||||
sni_container_refs=Unset, client_authentication=Unset,
|
sni_container_refs=Unset, client_authentication=Unset,
|
||||||
client_ca_tls_container_ref=Unset,
|
client_ca_tls_container_ref=Unset,
|
||||||
client_crl_container_ref=Unset, allowed_cidrs=Unset,
|
client_crl_container_ref=Unset, allowed_cidrs=Unset,
|
||||||
|
alpn_protocols=Unset,
|
||||||
return_object_only=True):
|
return_object_only=True):
|
||||||
"""Update a listener.
|
"""Update a listener.
|
||||||
|
|
||||||
|
@ -261,6 +265,8 @@ class ListenerClient(base_client.BaseLBaaSClient):
|
||||||
revocation list file for
|
revocation list file for
|
||||||
TERMINATED_HTTPS listeners.
|
TERMINATED_HTTPS listeners.
|
||||||
:param allowed_cidrs: A list of IPv4 or IPv6 CIDRs.
|
:param allowed_cidrs: A list of IPv4 or IPv6 CIDRs.
|
||||||
|
:param alpn_protocols: A list of ALPN protocols for TERMINATED_HTTPS
|
||||||
|
listeners.
|
||||||
:param return_object_only: If True, the response returns the object
|
:param return_object_only: If True, the response returns the object
|
||||||
inside the root tag. False returns the full
|
inside the root tag. False returns the full
|
||||||
response from the API.
|
response from the API.
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
import base64
|
import base64
|
||||||
import requests
|
import requests
|
||||||
import socket
|
import socket
|
||||||
|
import ssl
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from cryptography.hazmat.primitives import serialization
|
from cryptography.hazmat.primitives import serialization
|
||||||
|
@ -1094,3 +1095,77 @@ class TLSWithBarbicanTest(test_base.LoadBalancerBaseTestWithCompute):
|
||||||
LISTENER1_TCP_PORT),
|
LISTENER1_TCP_PORT),
|
||||||
timeout=12, verify=False, cert=(cert_file.name,
|
timeout=12, verify=False, cert=(cert_file.name,
|
||||||
key_file.name))
|
key_file.name))
|
||||||
|
|
||||||
|
@decorators.idempotent_id('19bade6f-302f-45dc-b316-553f1dfff49c')
|
||||||
|
def test_alpn_tls_traffic(self):
|
||||||
|
"""Test ALPN protocol negotiation"""
|
||||||
|
s_protos = c_protos = ['http/1.1']
|
||||||
|
expected = 'http/1.1'
|
||||||
|
self._test_alpn_tls_traffic(s_protos, c_protos, expected)
|
||||||
|
|
||||||
|
@decorators.idempotent_id('ee0d15a3-05b7-498d-9b2f-280d4896e597')
|
||||||
|
def test_alpn_fallback_tls_traffic(self):
|
||||||
|
"""Test ALPN protocol negotiation fallback"""
|
||||||
|
s_protos = ['http/1.0', 'http/1.1']
|
||||||
|
c_protos = ['bogus', 'h2', 'http/1.1']
|
||||||
|
expected = 'http/1.1'
|
||||||
|
self._test_alpn_tls_traffic(s_protos, c_protos, expected)
|
||||||
|
|
||||||
|
@decorators.idempotent_id('56f4274a-ebd9-42f7-b897-baebc4b8eb5b')
|
||||||
|
def test_alpn_proto_not_supported_tls_traffic(self):
|
||||||
|
"""Test failed ALPN protocol negotiation"""
|
||||||
|
s_protos = ['http/1.1', 'http/1.0']
|
||||||
|
c_protos = ['h2']
|
||||||
|
expected = None
|
||||||
|
self._test_alpn_tls_traffic(s_protos, c_protos, expected)
|
||||||
|
|
||||||
|
def _test_alpn_tls_traffic(self, s_protos, c_protos, expected_proto):
|
||||||
|
"""Test ALPN protocols between client and load balancer.
|
||||||
|
|
||||||
|
:param s_protos: ALPN protocols the load balancer accepts during the
|
||||||
|
SSL/TLS handshake.
|
||||||
|
:type s_protos: list of str
|
||||||
|
:param c_protos: ALPN protocols the client advertise during SSL/TLS the
|
||||||
|
handshake.
|
||||||
|
:type c_protos: list of str
|
||||||
|
:param expected_proto: the expected ALPN protocol selected during the
|
||||||
|
SSL/TLS handshake. Setting to ``None`` means
|
||||||
|
parties could not agree on ALPN protocol.
|
||||||
|
:type expected_proto: str
|
||||||
|
:raises self.skipException: ALPN support not available prior to v2.20.
|
||||||
|
"""
|
||||||
|
if not self.mem_listener_client.is_version_supported(
|
||||||
|
self.api_version, '2.20'):
|
||||||
|
raise self.skipException('ALPN protocols are only available on '
|
||||||
|
'Octavia API version 2.20 or newer.')
|
||||||
|
listener_name = data_utils.rand_name("lb_member_listener1-tls-alpn")
|
||||||
|
listener_kwargs = {
|
||||||
|
const.NAME: listener_name,
|
||||||
|
const.PROTOCOL: const.TERMINATED_HTTPS,
|
||||||
|
const.PROTOCOL_PORT: '443',
|
||||||
|
const.LOADBALANCER_ID: self.lb_id,
|
||||||
|
const.DEFAULT_POOL_ID: self.pool_id,
|
||||||
|
const.DEFAULT_TLS_CONTAINER_REF: self.server_secret_ref,
|
||||||
|
const.ALPN_PROTOCOLS: s_protos,
|
||||||
|
}
|
||||||
|
listener = self.mem_listener_client.create_listener(**listener_kwargs)
|
||||||
|
self.listener_id = listener[const.ID]
|
||||||
|
self.addCleanup(
|
||||||
|
self.mem_listener_client.cleanup_listener,
|
||||||
|
self.listener_id,
|
||||||
|
lb_client=self.mem_lb_client, lb_id=self.lb_id)
|
||||||
|
|
||||||
|
waiters.wait_for_status(self.mem_lb_client.show_loadbalancer,
|
||||||
|
self.lb_id, const.PROVISIONING_STATUS,
|
||||||
|
const.ACTIVE,
|
||||||
|
CONF.load_balancer.build_interval,
|
||||||
|
CONF.load_balancer.build_timeout)
|
||||||
|
|
||||||
|
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
|
||||||
|
context.set_alpn_protocols(c_protos)
|
||||||
|
s = socket.socket()
|
||||||
|
ssl_sock = context.wrap_socket(s)
|
||||||
|
ssl_sock.connect((self.lb_vip_address, 443))
|
||||||
|
selected_proto = ssl_sock.selected_alpn_protocol()
|
||||||
|
|
||||||
|
self.assertEqual(expected_proto, selected_proto)
|
||||||
|
|
Loading…
Reference in New Issue