Implement provider drivers - Listener
This patch adds provider driver support to the Octavia v2 Listener API. This patch also creates a provider driver for Octavia, fully implementing the listener methods. This patch also corrects the basic cookbook example for adding SNI certificates to a listener. Follow on patches will implement the remain parts of the API. Story: 1655768 Task: 5165 Depends-On: https://review.openstack.org/492311 Change-Id: I386097197f51d94b34f9a7fd7af7b36238294faf
This commit is contained in:
parent
7b2621fe29
commit
7a24b08434
doc/source/user/guides
octavia
api
common
tests
functional/api/v2
unit/api/drivers
specs/version1.1
@ -461,7 +461,7 @@ listener using Server Name Indication (SNI) technology.
|
||||
openstack loadbalancer create --name lb1 --vip-subnet-id public-subnet
|
||||
# Re-run the following until lb1 shows ACTIVE and ONLINE statuses:
|
||||
openstack loadbalancer show lb1
|
||||
openstack loadbalancer listener create --protocol-port 443 --protocol TERMINATED_HTTPS --name listener1 --default-tls-container=$(openstack secret list | awk '/ tls_secret1 / {print $2}') --sni-container_refs $(openstack secret list | awk '/ tls_secret1 / {print $2}') $(openstack secret list | awk '/ tls_secret2 / {print $2}') lb1
|
||||
openstack loadbalancer listener create --protocol-port 443 --protocol TERMINATED_HTTPS --name listener1 --default-tls-container=$(openstack secret list | awk '/ tls_secret1 / {print $2}') --sni-container-refs $(openstack secret list | awk '/ tls_secret1 / {print $2}') $(openstack secret list | awk '/ tls_secret2 / {print $2}') -- lb1
|
||||
openstack loadbalancer pool create --name pool1 --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTP
|
||||
openstack loadbalancer member create --subnet-id private-subnet --address 192.0.2.10 --protocol-port 80 pool1
|
||||
openstack loadbalancer member create --subnet-id private-subnet --address 192.0.2.11 --protocol-port 80 pool1
|
||||
|
@ -90,7 +90,14 @@ class AmphoraProviderDriver(driver_base.ProviderDriver):
|
||||
self.client.cast({}, 'delete_listener', **payload)
|
||||
|
||||
def listener_update(self, listener):
|
||||
pass
|
||||
listener_dict = listener.to_dict()
|
||||
if 'admin_state_up' in listener_dict:
|
||||
listener_dict['enabled'] = listener_dict.pop('admin_state_up')
|
||||
listener_id = listener_dict.pop('listener_id')
|
||||
|
||||
payload = {consts.LISTENER_ID: listener_id,
|
||||
consts.LISTENER_UPDATES: listener_dict}
|
||||
self.client.cast({}, 'update_listener', **payload)
|
||||
|
||||
# Pool
|
||||
def pool_create(self, pool):
|
||||
|
@ -42,6 +42,7 @@ class BaseDataModel(object):
|
||||
ret[attr].append(
|
||||
item.to_dict(calling_classes=(
|
||||
calling_classes + [type(self)]),
|
||||
recurse=True,
|
||||
render_unsets=render_unsets))
|
||||
else:
|
||||
ret[attr].append(None)
|
||||
@ -125,18 +126,21 @@ class LoadBalancer(BaseDataModel):
|
||||
class Listener(BaseDataModel):
|
||||
def __init__(self, admin_state_up=Unset, connection_limit=Unset,
|
||||
default_pool=Unset, default_pool_id=Unset,
|
||||
default_tls_container=Unset, description=Unset,
|
||||
default_tls_container_ref=Unset,
|
||||
default_tls_container_data=Unset, description=Unset,
|
||||
insert_headers=Unset, l7policies=Unset, listener_id=Unset,
|
||||
loadbalancer_id=Unset, name=Unset, protocol=Unset,
|
||||
protocol_port=Unset, sni_containers=Unset,
|
||||
timeout_client_data=Unset, timeout_member_connect=Unset,
|
||||
timeout_member_data=Unset, timeout_tcp_inspect=Unset):
|
||||
protocol_port=Unset, sni_container_refs=Unset,
|
||||
sni_container_data=Unset, timeout_client_data=Unset,
|
||||
timeout_member_connect=Unset, timeout_member_data=Unset,
|
||||
timeout_tcp_inspect=Unset):
|
||||
|
||||
self.admin_state_up = admin_state_up
|
||||
self.connection_limit = connection_limit
|
||||
self.default_pool = default_pool
|
||||
self.default_pool_id = default_pool_id
|
||||
self.default_tls_container = default_tls_container
|
||||
self.default_tls_container_data = default_tls_container_data
|
||||
self.default_tls_container_ref = default_tls_container_ref
|
||||
self.description = description
|
||||
self.insert_headers = insert_headers
|
||||
self.l7policies = l7policies
|
||||
@ -145,7 +149,8 @@ class Listener(BaseDataModel):
|
||||
self.name = name
|
||||
self.protocol = protocol
|
||||
self.protocol_port = protocol_port
|
||||
self.sni_containers = sni_containers
|
||||
self.sni_container_data = sni_container_data
|
||||
self.sni_container_refs = sni_container_refs
|
||||
self.timeout_client_data = timeout_client_data
|
||||
self.timeout_member_connect = timeout_member_connect
|
||||
self.timeout_member_data = timeout_member_data
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
import copy
|
||||
|
||||
import six
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from stevedore import driver as stevedore_driver
|
||||
@ -109,21 +111,26 @@ def lb_dict_to_provider_dict(lb_dict, vip=None,
|
||||
def db_listeners_to_provider_listeners(db_listeners):
|
||||
provider_listeners = []
|
||||
for listener in db_listeners:
|
||||
new_listener_dict = listener_dict_to_provider_dict(
|
||||
listener.to_dict(recurse=True))
|
||||
if ('default_pool' in new_listener_dict and
|
||||
new_listener_dict['default_pool']):
|
||||
provider_pool = db_pool_to_provider_pool(listener.default_pool)
|
||||
new_listener_dict['default_pool_id'] = provider_pool.pool_id
|
||||
new_listener_dict['default_pool'] = provider_pool
|
||||
if 'l7policies' in new_listener_dict:
|
||||
new_listener_dict['l7policies'] = (
|
||||
db_l7policies_to_provider_l7policies(listener.l7policies))
|
||||
provider_listeners.append(
|
||||
driver_dm.Listener.from_dict(new_listener_dict))
|
||||
provider_listener = db_listener_to_provider_listener(listener)
|
||||
provider_listeners.append(provider_listener)
|
||||
return provider_listeners
|
||||
|
||||
|
||||
def db_listener_to_provider_listener(db_listener):
|
||||
new_listener_dict = listener_dict_to_provider_dict(
|
||||
db_listener.to_dict(recurse=True))
|
||||
if ('default_pool' in new_listener_dict and
|
||||
new_listener_dict['default_pool']):
|
||||
provider_pool = db_pool_to_provider_pool(db_listener.default_pool)
|
||||
new_listener_dict['default_pool_id'] = provider_pool.pool_id
|
||||
new_listener_dict['default_pool'] = provider_pool
|
||||
if 'l7policies' in new_listener_dict:
|
||||
new_listener_dict['l7policies'] = (
|
||||
db_l7policies_to_provider_l7policies(db_listener.l7policies))
|
||||
provider_listener = driver_dm.Listener.from_dict(new_listener_dict)
|
||||
return provider_listener
|
||||
|
||||
|
||||
def listener_dict_to_provider_dict(listener_dict):
|
||||
new_listener_dict = _base_to_provider_dict(listener_dict)
|
||||
new_listener_dict['listener_id'] = new_listener_dict.pop('id')
|
||||
@ -133,9 +140,14 @@ def listener_dict_to_provider_dict(listener_dict):
|
||||
|
||||
# Pull the certs out of the certificate manager to pass to the provider
|
||||
if 'tls_certificate_id' in new_listener_dict:
|
||||
del new_listener_dict['tls_certificate_id']
|
||||
new_listener_dict['default_tls_container_ref'] = new_listener_dict.pop(
|
||||
'tls_certificate_id')
|
||||
if 'sni_containers' in new_listener_dict:
|
||||
del new_listener_dict['sni_containers']
|
||||
new_listener_dict['sni_container_refs'] = new_listener_dict.pop(
|
||||
'sni_containers')
|
||||
if 'sni_container_refs' in listener_dict:
|
||||
listener_dict['sni_containers'] = listener_dict.pop(
|
||||
'sni_container_refs')
|
||||
listener_obj = data_models.Listener(**listener_dict)
|
||||
if listener_obj.tls_certificate_id or listener_obj.sni_containers:
|
||||
SNI_objs = []
|
||||
@ -145,6 +157,9 @@ def listener_dict_to_provider_dict(listener_dict):
|
||||
elif isinstance(sni, dict):
|
||||
sni_obj = data_models.SNI(**sni)
|
||||
SNI_objs.append(sni_obj)
|
||||
elif isinstance(sni, six.string_types):
|
||||
sni_obj = data_models.SNI(tls_container_id=sni)
|
||||
SNI_objs.append(sni_obj)
|
||||
else:
|
||||
raise Exception(_('Invalid SNI container on listener'))
|
||||
listener_obj.sni_containers = SNI_objs
|
||||
@ -155,8 +170,14 @@ def listener_dict_to_provider_dict(listener_dict):
|
||||
).driver
|
||||
cert_dict = cert_parser.load_certificates_data(cert_manager,
|
||||
listener_obj)
|
||||
new_listener_dict['default_tls_container'] = cert_dict['tls_cert']
|
||||
new_listener_dict['sni_containers'] = cert_dict['sni_certs']
|
||||
if 'tls_cert' in cert_dict:
|
||||
new_listener_dict['default_tls_container_data'] = (
|
||||
cert_dict['tls_cert'].to_dict())
|
||||
if 'sni_certs' in cert_dict:
|
||||
sni_data_list = []
|
||||
for sni in cert_dict['sni_certs']:
|
||||
sni_data_list.append(sni.to_dict())
|
||||
new_listener_dict['sni_container_data'] = sni_data_list
|
||||
|
||||
# Remove the DB back references
|
||||
if 'load_balancer' in new_listener_dict:
|
||||
@ -173,11 +194,12 @@ def listener_dict_to_provider_dict(listener_dict):
|
||||
pool = new_listener_dict.pop('default_pool')
|
||||
new_listener_dict['default_pool'] = pool_dict_to_provider_dict(pool)
|
||||
provider_l7policies = []
|
||||
l7policies = new_listener_dict.pop('l7policies')
|
||||
for l7policy in l7policies:
|
||||
provider_l7policy = l7policy_dict_to_provider_dict(l7policy)
|
||||
provider_l7policies.append(provider_l7policy)
|
||||
new_listener_dict['l7policies'] = provider_l7policies
|
||||
if 'l7policies' in new_listener_dict:
|
||||
l7policies = new_listener_dict.pop('l7policies')
|
||||
for l7policy in l7policies:
|
||||
provider_l7policy = l7policy_dict_to_provider_dict(l7policy)
|
||||
provider_l7policies.append(provider_l7policy)
|
||||
new_listener_dict['l7policies'] = provider_l7policies
|
||||
return new_listener_dict
|
||||
|
||||
|
||||
|
@ -125,6 +125,13 @@ class BaseController(rest.RestController):
|
||||
show_deleted=show_deleted)
|
||||
return lb.project_id
|
||||
|
||||
def _get_lb_project_id_provider(self, session, id, show_deleted=True):
|
||||
"""Get the project_id of the load balancer from the database."""
|
||||
lb = self._get_db_obj(session, self.repositories.load_balancer,
|
||||
data_models.LoadBalancer, id,
|
||||
show_deleted=show_deleted)
|
||||
return lb.project_id, lb.provider
|
||||
|
||||
def _get_l7policy_project_id(self, session, id, show_deleted=True):
|
||||
"""Get the project_id of the load balancer from the database."""
|
||||
l7policy = self._get_db_obj(session, self.repositories.l7policy,
|
||||
|
@ -23,6 +23,9 @@ from stevedore import driver as stevedore_driver
|
||||
from wsme import types as wtypes
|
||||
from wsmeext import pecan as wsme_pecan
|
||||
|
||||
from octavia.api.drivers import data_models as driver_dm
|
||||
from octavia.api.drivers import driver_factory
|
||||
from octavia.api.drivers import utils as driver_utils
|
||||
from octavia.api.v2.controllers import base
|
||||
from octavia.api.v2.controllers import l7policy
|
||||
from octavia.api.v2.types import listener as listener_types
|
||||
@ -178,25 +181,6 @@ class ListenersController(base.BaseController):
|
||||
raise exceptions.InvalidOption(value=listener_dict.get('protocol'),
|
||||
option='protocol')
|
||||
|
||||
def _send_listener_to_handler(self, session, db_listener):
|
||||
try:
|
||||
LOG.info("Sending Creation of Listener %s to handler",
|
||||
db_listener.id)
|
||||
self.handler.create(db_listener)
|
||||
except Exception:
|
||||
with excutils.save_and_reraise_exception(
|
||||
reraise=False), db_api.get_lock_session() as lock_session:
|
||||
self._reset_lb_status(
|
||||
lock_session, lb_id=db_listener.load_balancer_id)
|
||||
# Listener now goes to ERROR
|
||||
self.repositories.listener.update(
|
||||
lock_session, db_listener.id,
|
||||
provisioning_status=constants.ERROR)
|
||||
db_listener = self._get_db_listener(session, db_listener.id)
|
||||
result = self._convert_db_to_type(db_listener,
|
||||
listener_types.ListenerResponse)
|
||||
return listener_types.ListenerRootResponse(listener=result)
|
||||
|
||||
@wsme_pecan.wsexpose(listener_types.ListenerRootResponse,
|
||||
body=listener_types.ListenerRootPOST, status_code=201)
|
||||
def post(self, listener_):
|
||||
@ -205,7 +189,7 @@ class ListenersController(base.BaseController):
|
||||
context = pecan.request.context.get('octavia_context')
|
||||
|
||||
load_balancer_id = listener.loadbalancer_id
|
||||
listener.project_id = self._get_lb_project_id(
|
||||
listener.project_id, provider = self._get_lb_project_id_provider(
|
||||
context.session, load_balancer_id)
|
||||
|
||||
self._auth_validate_action(context, listener.project_id,
|
||||
@ -216,6 +200,9 @@ class ListenersController(base.BaseController):
|
||||
raise exceptions.DisabledOption(
|
||||
value=constants.PROTOCOL_TERMINATED_HTTPS, option='protocol')
|
||||
|
||||
# Load the driver early as it also provides validation
|
||||
driver = driver_factory.get_driver(provider)
|
||||
|
||||
lock_session = db_api.get_session(autocommit=False)
|
||||
try:
|
||||
if self.repositories.check_quota_met(
|
||||
@ -237,12 +224,30 @@ class ListenersController(base.BaseController):
|
||||
|
||||
db_listener = self._validate_create_listener(
|
||||
lock_session, listener_dict)
|
||||
|
||||
# Prepare the data for the driver data model
|
||||
provider_listener = (
|
||||
driver_utils.db_listener_to_provider_listener(db_listener))
|
||||
|
||||
# re-inject the sni container references lost due to SNI
|
||||
# being a seperate table in the DB
|
||||
provider_listener.sni_container_refs = listener.sni_container_refs
|
||||
|
||||
# Dispatch to the driver
|
||||
LOG.info("Sending create Listener %s to provider %s",
|
||||
db_listener.id, driver.name)
|
||||
driver_utils.call_provider(
|
||||
driver.name, driver.listener_create, provider_listener)
|
||||
|
||||
lock_session.commit()
|
||||
except Exception:
|
||||
with excutils.save_and_reraise_exception():
|
||||
lock_session.rollback()
|
||||
|
||||
return self._send_listener_to_handler(context.session, db_listener)
|
||||
db_listener = self._get_db_listener(context.session, db_listener.id)
|
||||
result = self._convert_db_to_type(db_listener,
|
||||
listener_types.ListenerResponse)
|
||||
return listener_types.ListenerRootResponse(listener=result)
|
||||
|
||||
def _graph_create(self, lock_session, listener_dict,
|
||||
l7policies=None, pool_name_ids=None):
|
||||
@ -285,8 +290,10 @@ class ListenersController(base.BaseController):
|
||||
show_deleted=False)
|
||||
load_balancer_id = db_listener.load_balancer_id
|
||||
|
||||
self._auth_validate_action(context, db_listener.project_id,
|
||||
constants.RBAC_PUT)
|
||||
project_id, provider = self._get_lb_project_id_provider(
|
||||
context.session, load_balancer_id)
|
||||
|
||||
self._auth_validate_action(context, project_id, constants.RBAC_PUT)
|
||||
|
||||
# TODO(rm_work): Do we need something like this? What do we do on an
|
||||
# empty body for a PUT?
|
||||
@ -297,8 +304,6 @@ class ListenersController(base.BaseController):
|
||||
if listener.default_pool_id:
|
||||
self._validate_pool(context.session, load_balancer_id,
|
||||
listener.default_pool_id)
|
||||
self._test_lb_and_listener_statuses(context.session, load_balancer_id,
|
||||
id=id)
|
||||
|
||||
sni_containers = listener.sni_container_refs or []
|
||||
tls_refs = [sni for sni in sni_containers]
|
||||
@ -306,18 +311,33 @@ class ListenersController(base.BaseController):
|
||||
tls_refs.append(listener.default_tls_container_ref)
|
||||
self._validate_tls_refs(tls_refs)
|
||||
|
||||
try:
|
||||
LOG.info("Sending Update of Listener %s to handler", id)
|
||||
self.handler.update(db_listener, listener)
|
||||
except Exception:
|
||||
with excutils.save_and_reraise_exception(
|
||||
reraise=False), db_api.get_lock_session() as lock_session:
|
||||
self._reset_lb_status(
|
||||
lock_session, lb_id=db_listener.load_balancer_id)
|
||||
# Listener now goes to ERROR
|
||||
self.repositories.listener.update(
|
||||
lock_session, db_listener.id,
|
||||
provisioning_status=constants.ERROR)
|
||||
# Load the driver early as it also provides validation
|
||||
driver = driver_factory.get_driver(provider)
|
||||
|
||||
with db_api.get_lock_session() as lock_session:
|
||||
self._test_lb_and_listener_statuses(lock_session,
|
||||
load_balancer_id, id=id)
|
||||
|
||||
# Prepare the data for the driver data model
|
||||
listener_dict = listener.to_dict(render_unsets=False)
|
||||
listener_dict['id'] = id
|
||||
provider_listener_dict = (
|
||||
driver_utils.listener_dict_to_provider_dict(listener_dict))
|
||||
|
||||
# Dispatch to the driver
|
||||
LOG.info("Sending update Listener %s to provider %s", id,
|
||||
driver.name)
|
||||
driver_utils.call_provider(
|
||||
driver.name, driver.listener_update,
|
||||
driver_dm.Listener.from_dict(provider_listener_dict))
|
||||
|
||||
# Update the database to reflect what the driver just accepted
|
||||
self.repositories.listener.update(
|
||||
lock_session, id, **listener.to_dict(render_unsets=False))
|
||||
|
||||
# Force SQL alchemy to query the DB, otherwise we get inconsistent
|
||||
# results
|
||||
context.session.expire_all()
|
||||
db_listener = self._get_db_listener(context.session, id)
|
||||
result = self._convert_db_to_type(db_listener,
|
||||
listener_types.ListenerResponse)
|
||||
@ -331,26 +351,23 @@ class ListenersController(base.BaseController):
|
||||
show_deleted=False)
|
||||
load_balancer_id = db_listener.load_balancer_id
|
||||
|
||||
self._auth_validate_action(context, db_listener.project_id,
|
||||
constants.RBAC_DELETE)
|
||||
project_id, provider = self._get_lb_project_id_provider(
|
||||
context.session, load_balancer_id)
|
||||
|
||||
self._test_lb_and_listener_statuses(
|
||||
context.session, load_balancer_id,
|
||||
id=id, listener_status=constants.PENDING_DELETE)
|
||||
self._auth_validate_action(context, project_id, constants.RBAC_DELETE)
|
||||
|
||||
try:
|
||||
LOG.info("Sending Deletion of Listener %s to handler",
|
||||
db_listener.id)
|
||||
self.handler.delete(db_listener)
|
||||
except Exception:
|
||||
with excutils.save_and_reraise_exception(
|
||||
reraise=False), db_api.get_lock_session() as lock_session:
|
||||
self._reset_lb_status(
|
||||
lock_session, lb_id=db_listener.load_balancer_id)
|
||||
# Listener now goes to ERROR
|
||||
self.repositories.listener.update(
|
||||
lock_session, db_listener.id,
|
||||
provisioning_status=constants.ERROR)
|
||||
# Load the driver early as it also provides validation
|
||||
driver = driver_factory.get_driver(provider)
|
||||
|
||||
with db_api.get_lock_session() as lock_session:
|
||||
|
||||
self._test_lb_and_listener_statuses(
|
||||
lock_session, load_balancer_id,
|
||||
id=id, listener_status=constants.PENDING_DELETE)
|
||||
|
||||
LOG.info("Sending delete Listener %s to provider %s", id,
|
||||
driver.name)
|
||||
driver_utils.call_provider(driver.name, driver.listener_delete, id)
|
||||
|
||||
@pecan.expose()
|
||||
def _lookup(self, id, *remainder):
|
||||
|
@ -226,6 +226,7 @@ HEALTH_MONITOR_ID = 'health_monitor_id'
|
||||
L7POLICY_ID = 'l7policy_id'
|
||||
L7RULE_ID = 'l7rule_id'
|
||||
LOAD_BALANCER_UPDATES = 'load_balancer_updates'
|
||||
LISTENER_UPDATES = 'listener_updates'
|
||||
|
||||
CERT_ROTATE_AMPHORA_FLOW = 'octavia-cert-rotate-amphora-flow'
|
||||
CREATE_AMPHORA_FLOW = 'octavia-create-amphora-flow'
|
||||
|
@ -23,6 +23,7 @@ from oslo_utils import uuidutils
|
||||
from octavia.common import constants
|
||||
import octavia.common.context
|
||||
from octavia.common import data_models
|
||||
from octavia.common import exceptions
|
||||
from octavia.tests.functional.api.v2 import base
|
||||
|
||||
|
||||
@ -433,7 +434,14 @@ class TestListener(base.BaseAPITest):
|
||||
listener_path = self.listener_path
|
||||
self.get(listener_path.format(listener_id='SEAN-CONNERY'), status=404)
|
||||
|
||||
def test_create(self, response_status=201, **optionals):
|
||||
# TODO(johnsom) Fix this when there is a noop certificate manager
|
||||
@mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
|
||||
def test_create(self, mock_cert_data, response_status=201, **optionals):
|
||||
cert1 = data_models.TLSContainer(certificate='cert 1')
|
||||
cert2 = data_models.TLSContainer(certificate='cert 2')
|
||||
cert3 = data_models.TLSContainer(certificate='cert 3')
|
||||
mock_cert_data.return_value = {'tls_cert': cert1,
|
||||
'sni_certs': [cert2, cert3]}
|
||||
sni1 = uuidutils.generate_uuid()
|
||||
sni2 = uuidutils.generate_uuid()
|
||||
lb_listener = {'name': 'listener1', 'default_pool_id': None,
|
||||
@ -630,18 +638,27 @@ class TestListener(base.BaseAPITest):
|
||||
body = self._build_body(lb_listener)
|
||||
self.post(self.LISTENERS_PATH, body, status=403)
|
||||
|
||||
def test_create_with_bad_handler(self):
|
||||
self.handler_mock().listener.create.side_effect = Exception()
|
||||
api_listener = self.create_listener(
|
||||
constants.PROTOCOL_HTTP, 80,
|
||||
self.lb_id).get(self.root_tag)
|
||||
self.assert_correct_status(
|
||||
lb_id=self.lb_id,
|
||||
listener_id=api_listener.get('id'),
|
||||
listener_prov_status=constants.ERROR,
|
||||
listener_op_status=constants.OFFLINE)
|
||||
@mock.patch('octavia.api.drivers.utils.call_provider')
|
||||
def test_create_with_bad_provider(self, mock_provider):
|
||||
mock_provider.side_effect = exceptions.ProviderDriverError(
|
||||
prov='bad_driver', user_msg='broken')
|
||||
lb_listener = {'name': 'listener1',
|
||||
'protocol': constants.PROTOCOL_HTTP,
|
||||
'protocol_port': 80,
|
||||
'loadbalancer_id': self.lb_id}
|
||||
body = self._build_body(lb_listener)
|
||||
response = self.post(self.LISTENERS_PATH, body, status=500)
|
||||
self.assertIn('Provider \'bad_driver\' reports error: broken',
|
||||
response.json.get('faultstring'))
|
||||
|
||||
def test_create_authorized(self, **optionals):
|
||||
# TODO(johnsom) Fix this when there is a noop certificate manager
|
||||
@mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
|
||||
def test_create_authorized(self, mock_cert_data, **optionals):
|
||||
cert1 = data_models.TLSContainer(certificate='cert 1')
|
||||
cert2 = data_models.TLSContainer(certificate='cert 2')
|
||||
cert3 = data_models.TLSContainer(certificate='cert 3')
|
||||
mock_cert_data.return_value = {'tls_cert': cert1,
|
||||
'sni_certs': [cert2, cert3]}
|
||||
sni1 = uuidutils.generate_uuid()
|
||||
sni2 = uuidutils.generate_uuid()
|
||||
lb_listener = {'name': 'listener1', 'default_pool_id': None,
|
||||
@ -731,21 +748,23 @@ class TestListener(base.BaseAPITest):
|
||||
self.conf.config(group='api_settings', auth_strategy=auth_strategy)
|
||||
self.assertEqual(self.NOT_AUTHORIZED_BODY, response.json)
|
||||
|
||||
def test_update_with_bad_handler(self):
|
||||
@mock.patch('octavia.api.drivers.utils.call_provider')
|
||||
def test_update_with_bad_provider(self, mock_provider):
|
||||
api_listener = self.create_listener(
|
||||
constants.PROTOCOL_HTTP, 80,
|
||||
self.lb_id).get(self.root_tag)
|
||||
self.set_lb_status(lb_id=self.lb_id)
|
||||
new_listener = {'name': 'new_name'}
|
||||
self.handler_mock().listener.update.side_effect = Exception()
|
||||
self.put(self.LISTENER_PATH.format(listener_id=api_listener.get('id')),
|
||||
self._build_body(new_listener))
|
||||
self.assert_correct_status(
|
||||
lb_id=self.lb_id,
|
||||
listener_id=api_listener.get('id'),
|
||||
listener_prov_status=constants.ERROR)
|
||||
mock_provider.side_effect = exceptions.ProviderDriverError(
|
||||
prov='bad_driver', user_msg='broken')
|
||||
response = self.put(
|
||||
self.LISTENER_PATH.format(listener_id=api_listener.get('id')),
|
||||
self._build_body(new_listener), status=500)
|
||||
self.assertIn('Provider \'bad_driver\' reports error: broken',
|
||||
response.json.get('faultstring'))
|
||||
|
||||
def test_delete_with_bad_handler(self):
|
||||
@mock.patch('octavia.api.drivers.utils.call_provider')
|
||||
def test_delete_with_bad_provider(self, mock_provider):
|
||||
api_listener = self.create_listener(
|
||||
constants.PROTOCOL_HTTP, 80,
|
||||
self.lb_id).get(self.root_tag)
|
||||
@ -755,19 +774,19 @@ class TestListener(base.BaseAPITest):
|
||||
api_listener['operating_status'] = constants.ONLINE
|
||||
response = self.get(self.LISTENER_PATH.format(
|
||||
listener_id=api_listener.get('id'))).json.get(self.root_tag)
|
||||
|
||||
self.assertIsNone(api_listener.pop('updated_at'))
|
||||
self.assertIsNotNone(response.pop('updated_at'))
|
||||
self.assertEqual(api_listener, response)
|
||||
self.handler_mock().listener.delete.side_effect = Exception()
|
||||
mock_provider.side_effect = exceptions.ProviderDriverError(
|
||||
prov='bad_driver', user_msg='broken')
|
||||
self.delete(self.LISTENER_PATH.format(
|
||||
listener_id=api_listener.get('id')))
|
||||
self.assert_correct_status(
|
||||
lb_id=self.lb_id,
|
||||
listener_id=api_listener.get('id'),
|
||||
listener_prov_status=constants.ERROR)
|
||||
listener_id=api_listener.get('id')), status=500)
|
||||
|
||||
def test_update(self):
|
||||
# TODO(johnsom) Fix this when there is a noop certificate manager
|
||||
@mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
|
||||
def test_update(self, mock_cert_data):
|
||||
cert1 = data_models.TLSContainer(certificate='cert 1')
|
||||
mock_cert_data.return_value = {'tls_cert': cert1}
|
||||
tls_uuid = uuidutils.generate_uuid()
|
||||
listener = self.create_listener(
|
||||
constants.PROTOCOL_TCP, 80, self.lb_id,
|
||||
@ -821,7 +840,11 @@ class TestListener(base.BaseAPITest):
|
||||
self.assert_final_listener_statuses(self.lb_id,
|
||||
listener['listener']['id'])
|
||||
|
||||
def test_update_authorized(self):
|
||||
# TODO(johnsom) Fix this when there is a noop certificate manager
|
||||
@mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
|
||||
def test_update_authorized(self, mock_cert_data):
|
||||
cert1 = data_models.TLSContainer(certificate='cert 1')
|
||||
mock_cert_data.return_value = {'tls_cert': cert1}
|
||||
tls_uuid = uuidutils.generate_uuid()
|
||||
listener = self.create_listener(
|
||||
constants.PROTOCOL_TCP, 80, self.lb_id,
|
||||
@ -875,7 +898,11 @@ class TestListener(base.BaseAPITest):
|
||||
self.assert_final_listener_statuses(self.lb_id,
|
||||
api_listener['id'])
|
||||
|
||||
def test_update_not_authorized(self):
|
||||
# TODO(johnsom) Fix this when there is a noop certificate manager
|
||||
@mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
|
||||
def test_update_not_authorized(self, mock_cert_data):
|
||||
cert1 = data_models.TLSContainer(certificate='cert 1')
|
||||
mock_cert_data.return_value = {'tls_cert': cert1}
|
||||
tls_uuid = uuidutils.generate_uuid()
|
||||
listener = self.create_listener(
|
||||
constants.PROTOCOL_TCP, 80, self.lb_id,
|
||||
@ -1062,7 +1089,12 @@ class TestListener(base.BaseAPITest):
|
||||
listener_id=listener['listener'].get('id'))
|
||||
self.put(listener_path, {}, status=400)
|
||||
|
||||
def test_update_bad_tls_ref(self):
|
||||
# TODO(johnsom) Fix this when there is a noop certificate manager
|
||||
@mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
|
||||
def test_update_bad_tls_ref(self, mock_cert_data):
|
||||
cert2 = data_models.TLSContainer(certificate='cert 2')
|
||||
cert3 = data_models.TLSContainer(certificate='cert 3')
|
||||
mock_cert_data.return_value = {'sni_certs': [cert2, cert3]}
|
||||
sni1 = uuidutils.generate_uuid()
|
||||
sni2 = uuidutils.generate_uuid()
|
||||
tls_ref = uuidutils.generate_uuid()
|
||||
@ -1202,7 +1234,14 @@ class TestListener(base.BaseAPITest):
|
||||
listener_id=api_listener['id'])
|
||||
self.delete(listener_path, status=404)
|
||||
|
||||
def test_create_with_tls_termination_data(self):
|
||||
# TODO(johnsom) Fix this when there is a noop certificate manager
|
||||
@mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
|
||||
def test_create_with_tls_termination_data(self, mock_cert_data):
|
||||
cert1 = data_models.TLSContainer(certificate='cert 1')
|
||||
cert2 = data_models.TLSContainer(certificate='cert 2')
|
||||
cert3 = data_models.TLSContainer(certificate='cert 3')
|
||||
mock_cert_data.return_value = {'tls_cert': cert1,
|
||||
'sni_certs': [cert2, cert3]}
|
||||
cert_id = uuidutils.generate_uuid()
|
||||
listener = self.create_listener(constants.PROTOCOL_TERMINATED_HTTPS,
|
||||
80, self.lb_id,
|
||||
@ -1212,7 +1251,11 @@ class TestListener(base.BaseAPITest):
|
||||
get_listener = self.get(listener_path).json['listener']
|
||||
self.assertEqual(cert_id, get_listener['default_tls_container_ref'])
|
||||
|
||||
def test_update_with_tls_termination_data(self):
|
||||
# TODO(johnsom) Fix this when there is a noop certificate manager
|
||||
@mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
|
||||
def test_update_with_tls_termination_data(self, mock_cert_data):
|
||||
cert1 = data_models.TLSContainer(certificate='cert 1')
|
||||
mock_cert_data.return_value = {'tls_cert': cert1}
|
||||
cert_id = uuidutils.generate_uuid()
|
||||
listener = self.create_listener(constants.PROTOCOL_TERMINATED_HTTPS,
|
||||
80, self.lb_id)
|
||||
@ -1224,7 +1267,8 @@ class TestListener(base.BaseAPITest):
|
||||
self.put(listener_path,
|
||||
self._build_body({'default_tls_container_ref': cert_id}))
|
||||
get_listener = self.get(listener_path).json['listener']
|
||||
self.assertIsNone(get_listener.get('default_tls_container_ref'))
|
||||
self.assertEqual(cert_id,
|
||||
get_listener.get('default_tls_container_ref'))
|
||||
|
||||
def test_create_with_tls_termination_disabled(self):
|
||||
self.conf.config(group='api_settings',
|
||||
@ -1239,7 +1283,14 @@ class TestListener(base.BaseAPITest):
|
||||
.format(constants.PROTOCOL_TERMINATED_HTTPS),
|
||||
listener.get('faultstring'))
|
||||
|
||||
def test_create_with_sni_data(self):
|
||||
# TODO(johnsom) Fix this when there is a noop certificate manager
|
||||
@mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
|
||||
def test_create_with_sni_data(self, mock_cert_data):
|
||||
cert1 = data_models.TLSContainer(certificate='cert 1')
|
||||
cert2 = data_models.TLSContainer(certificate='cert 2')
|
||||
cert3 = data_models.TLSContainer(certificate='cert 3')
|
||||
mock_cert_data.return_value = {'tls_cert': cert1,
|
||||
'sni_certs': [cert2, cert3]}
|
||||
sni_id1 = uuidutils.generate_uuid()
|
||||
sni_id2 = uuidutils.generate_uuid()
|
||||
listener = self.create_listener(constants.PROTOCOL_HTTP, 80,
|
||||
@ -1251,7 +1302,12 @@ class TestListener(base.BaseAPITest):
|
||||
self.assertItemsEqual([sni_id1, sni_id2],
|
||||
get_listener['sni_container_refs'])
|
||||
|
||||
def test_update_with_sni_data(self):
|
||||
# TODO(johnsom) Fix this when there is a noop certificate manager
|
||||
@mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
|
||||
def test_update_with_sni_data(self, mock_cert_data):
|
||||
cert2 = data_models.TLSContainer(certificate='cert 2')
|
||||
cert3 = data_models.TLSContainer(certificate='cert 3')
|
||||
mock_cert_data.return_value = {'sni_certs': [cert2, cert3]}
|
||||
sni_id1 = uuidutils.generate_uuid()
|
||||
sni_id2 = uuidutils.generate_uuid()
|
||||
listener = self.create_listener(constants.PROTOCOL_HTTP, 80,
|
||||
|
@ -2350,8 +2350,11 @@ class TestLoadBalancerGraph(base.BaseAPITest):
|
||||
# TODO(johnsom) Fix this when there is a noop certificate manager
|
||||
@mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
|
||||
def test_with_one_listener_sni_containers(self, mock_cert_data):
|
||||
mock_cert_data.return_value = {'tls_cert': 'cert 1',
|
||||
'sni_certs': ['cert 2', 'cert 3']}
|
||||
cert1 = data_models.TLSContainer(certificate='cert 1')
|
||||
cert2 = data_models.TLSContainer(certificate='cert 2')
|
||||
cert3 = data_models.TLSContainer(certificate='cert 3')
|
||||
mock_cert_data.return_value = {'tls_cert': cert1,
|
||||
'sni_certs': [cert2, cert3]}
|
||||
create_sni_containers, expected_sni_containers = (
|
||||
self._get_sni_container_bodies())
|
||||
create_listener, expected_listener = self._get_listener_bodies(
|
||||
@ -2512,9 +2515,11 @@ class TestLoadBalancerGraph(base.BaseAPITest):
|
||||
# TODO(johnsom) Fix this when there is a noop certificate manager
|
||||
@mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
|
||||
def test_with_one_of_everything(self, mock_cert_data):
|
||||
mock_cert_data.return_value = {'tls_cert': 'cert 1',
|
||||
'sni_certs': ['cert 2', 'cert 3']}
|
||||
|
||||
cert1 = data_models.TLSContainer(certificate='cert 1')
|
||||
cert2 = data_models.TLSContainer(certificate='cert 2')
|
||||
cert3 = data_models.TLSContainer(certificate='cert 3')
|
||||
mock_cert_data.return_value = {'tls_cert': cert1,
|
||||
'sni_certs': [cert2, cert3]}
|
||||
body, expected_lb = self._test_with_one_of_everything_helper()
|
||||
response = self.post(self.LBS_PATH, body)
|
||||
api_lb = response.json.get(self.root_tag)
|
||||
@ -2599,9 +2604,11 @@ class TestLoadBalancerGraph(base.BaseAPITest):
|
||||
# TODO(johnsom) Fix this when there is a noop certificate manager
|
||||
@mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
|
||||
def test_create_over_quota_sanity_check(self, mock_cert_data):
|
||||
mock_cert_data.return_value = {'tls_cert': 'cert 1',
|
||||
'sni_certs': ['cert 2', 'cert 3']}
|
||||
|
||||
cert1 = data_models.TLSContainer(certificate='cert 1')
|
||||
cert2 = data_models.TLSContainer(certificate='cert 2')
|
||||
cert3 = data_models.TLSContainer(certificate='cert 3')
|
||||
mock_cert_data.return_value = {'tls_cert': cert1,
|
||||
'sni_certs': [cert2, cert3]}
|
||||
# This one should create, as we don't check quotas on L7Policies
|
||||
body, _ = self._test_with_one_of_everything_helper()
|
||||
self.start_quota_mock(data_models.L7Policy)
|
||||
|
@ -33,12 +33,16 @@ class TestProviderDataModels(base.TestCase):
|
||||
self.vip_subnet_id = uuidutils.generate_uuid()
|
||||
self.listener_id = uuidutils.generate_uuid()
|
||||
self.vip_qos_policy_id = uuidutils.generate_uuid()
|
||||
self.default_tls_container_ref = uuidutils.generate_uuid()
|
||||
self.sni_container_ref_1 = uuidutils.generate_uuid()
|
||||
self.sni_container_ref_2 = uuidutils.generate_uuid()
|
||||
|
||||
self.ref_listener = data_models.Listener(
|
||||
admin_state_up=True,
|
||||
connection_limit=5000,
|
||||
default_pool_id=None,
|
||||
default_tls_container='a_pkcs12_bundle',
|
||||
default_tls_container_data='default_cert_data',
|
||||
default_tls_container_ref=self.default_tls_container_ref,
|
||||
description='The listener',
|
||||
insert_headers={'X-Forwarded-For': 'true'},
|
||||
l7policies=[],
|
||||
@ -47,7 +51,9 @@ class TestProviderDataModels(base.TestCase):
|
||||
name='super_listener',
|
||||
protocol='avian',
|
||||
protocol_port=42,
|
||||
sni_containers='another_pkcs12_bundle')
|
||||
sni_container_data=['sni_cert_data_1', 'sni_cert_data_2'],
|
||||
sni_container_refs=[self.sni_container_ref_1,
|
||||
self.sni_container_ref_2])
|
||||
|
||||
self.ref_lb = data_models.LoadBalancer(
|
||||
admin_state_up=False,
|
||||
@ -75,18 +81,23 @@ class TestProviderDataModels(base.TestCase):
|
||||
'name': 'favorite_lb',
|
||||
'vip_qos_policy_id': self.vip_qos_policy_id}
|
||||
|
||||
self.ref_listener = {'admin_state_up': True,
|
||||
'connection_limit': 5000,
|
||||
'default_pool_id': None,
|
||||
'default_tls_container': 'a_pkcs12_bundle',
|
||||
'description': 'The listener',
|
||||
'insert_headers': {'X-Forwarded-For': 'true'},
|
||||
'listener_id': self.listener_id,
|
||||
'loadbalancer_id': self.loadbalancer_id,
|
||||
'name': 'super_listener',
|
||||
'protocol': 'avian',
|
||||
'protocol_port': 42,
|
||||
'sni_containers': 'another_pkcs12_bundle'}
|
||||
self.ref_listener = {
|
||||
'admin_state_up': True,
|
||||
'connection_limit': 5000,
|
||||
'default_pool_id': None,
|
||||
'default_tls_container_data': 'default_cert_data',
|
||||
'default_tls_container_ref': self.default_tls_container_ref,
|
||||
'description': 'The listener',
|
||||
'insert_headers': {'X-Forwarded-For': 'true'},
|
||||
'listener_id': self.listener_id,
|
||||
'l7policies': [],
|
||||
'loadbalancer_id': self.loadbalancer_id,
|
||||
'name': 'super_listener',
|
||||
'protocol': 'avian',
|
||||
'protocol_port': 42,
|
||||
'sni_container_data': ['sni_cert_data_1', 'sni_cert_data_2'],
|
||||
'sni_container_refs': [self.sni_container_ref_1,
|
||||
self.sni_container_ref_2]}
|
||||
|
||||
self.ref_lb_dict_with_listener = {
|
||||
'admin_state_up': False,
|
||||
|
@ -38,6 +38,9 @@ class TestNoopProviderDriver(base.TestCase):
|
||||
self.l7policy_id = uuidutils.generate_uuid()
|
||||
self.l7rule_id = uuidutils.generate_uuid()
|
||||
self.project_id = uuidutils.generate_uuid()
|
||||
self.default_tls_container_ref = uuidutils.generate_uuid()
|
||||
self.sni_container_ref_1 = uuidutils.generate_uuid()
|
||||
self.sni_container_ref_2 = uuidutils.generate_uuid()
|
||||
|
||||
self.ref_vip = data_models.VIP(
|
||||
vip_address=self.vip_address,
|
||||
@ -110,7 +113,8 @@ class TestNoopProviderDriver(base.TestCase):
|
||||
connection_limit=5,
|
||||
default_pool=self.ref_pool,
|
||||
default_pool_id=self.pool_id,
|
||||
default_tls_container='a_pkcs12_bundle',
|
||||
default_tls_container_data='default_cert_data',
|
||||
default_tls_container_ref=self.default_tls_container_ref,
|
||||
description='The listener',
|
||||
insert_headers={'X-Forwarded-For': 'true'},
|
||||
l7policies=[self.ref_l7policy],
|
||||
@ -119,7 +123,9 @@ class TestNoopProviderDriver(base.TestCase):
|
||||
name='super_listener',
|
||||
protocol='avian',
|
||||
protocol_port=42,
|
||||
sni_containers='another_pkcs12_bundle')
|
||||
sni_container_data=['sni_cert_data_1', 'sni_cert_data_2'],
|
||||
sni_container_refs=[self.sni_container_ref_1,
|
||||
self.sni_container_ref_2])
|
||||
|
||||
self.ref_lb = data_models.LoadBalancer(
|
||||
admin_state_up=False,
|
||||
|
@ -53,8 +53,9 @@ class TestUtils(base.TestCase):
|
||||
self.network_id = uuidutils.generate_uuid()
|
||||
self.subnet_id = uuidutils.generate_uuid()
|
||||
self.qos_policy_id = uuidutils.generate_uuid()
|
||||
self.sni_containers = [{'tls_container_id': '2'},
|
||||
{'tls_container_id': '3'}]
|
||||
self.default_tls_container_ref = uuidutils.generate_uuid()
|
||||
self.sni_container_ref_1 = uuidutils.generate_uuid()
|
||||
self.sni_container_ref_2 = uuidutils.generate_uuid()
|
||||
|
||||
_common_test_dict = {'provisioning_status': constants.ACTIVE,
|
||||
'operating_status': constants.ONLINE,
|
||||
@ -356,27 +357,29 @@ class TestUtils(base.TestCase):
|
||||
self.provider_l7policy2]
|
||||
|
||||
# Setup Listeners
|
||||
self.test_listener1_dict = {'id': listener1_id,
|
||||
'name': 'listener_1',
|
||||
'description': 'Listener 1',
|
||||
'default_pool_id': pool1_id,
|
||||
'load_balancer_id': self.lb_id,
|
||||
'protocol': 'avian',
|
||||
'protocol_port': 90,
|
||||
'connection_limit': 10000,
|
||||
'tls_certificate_id': '1',
|
||||
'stats': None,
|
||||
'default_pool': self.test_pool1_dict,
|
||||
'load_balancer': None,
|
||||
'sni_containers': self.sni_containers,
|
||||
'peer_port': 55,
|
||||
'l7policies': self.test_l7policies,
|
||||
'insert_headers': {},
|
||||
'pools': None,
|
||||
'timeout_client_data': 1000,
|
||||
'timeout_member_connect': 2000,
|
||||
'timeout_member_data': 3000,
|
||||
'timeout_tcp_inspect': 4000}
|
||||
self.test_listener1_dict = {
|
||||
'id': listener1_id,
|
||||
'name': 'listener_1',
|
||||
'description': 'Listener 1',
|
||||
'default_pool_id': pool1_id,
|
||||
'load_balancer_id': self.lb_id,
|
||||
'protocol': 'avian',
|
||||
'protocol_port': 90,
|
||||
'connection_limit': 10000,
|
||||
'tls_certificate_id': self.default_tls_container_ref,
|
||||
'stats': None,
|
||||
'default_pool': self.test_pool1_dict,
|
||||
'load_balancer': None,
|
||||
'sni_containers': [self.sni_container_ref_1,
|
||||
self.sni_container_ref_2],
|
||||
'peer_port': 55,
|
||||
'l7policies': self.test_l7policies,
|
||||
'insert_headers': {},
|
||||
'pools': None,
|
||||
'timeout_client_data': 1000,
|
||||
'timeout_member_connect': 2000,
|
||||
'timeout_member_data': 3000,
|
||||
'timeout_tcp_inspect': 4000}
|
||||
|
||||
self.test_listener1_dict.update(_common_test_dict)
|
||||
|
||||
@ -403,12 +406,17 @@ class TestUtils(base.TestCase):
|
||||
|
||||
self.test_db_listeners = [self.db_listener1, self.db_listener2]
|
||||
|
||||
cert1 = data_models.TLSContainer(certificate='cert 1')
|
||||
cert2 = data_models.TLSContainer(certificate='cert 2')
|
||||
cert3 = data_models.TLSContainer(certificate='cert 3')
|
||||
|
||||
self.provider_listener1_dict = {
|
||||
'admin_state_up': True,
|
||||
'connection_limit': 10000,
|
||||
'default_pool': self.provider_pool1_dict,
|
||||
'default_pool_id': pool1_id,
|
||||
'default_tls_container': 'cert 1',
|
||||
'default_tls_container_data': cert1.to_dict(),
|
||||
'default_tls_container_ref': self.default_tls_container_ref,
|
||||
'description': 'Listener 1',
|
||||
'insert_headers': {},
|
||||
'l7policies': self.provider_l7policies_dict,
|
||||
@ -417,7 +425,9 @@ class TestUtils(base.TestCase):
|
||||
'name': 'listener_1',
|
||||
'protocol': 'avian',
|
||||
'protocol_port': 90,
|
||||
'sni_containers': ['cert 2', 'cert 3'],
|
||||
'sni_container_data': [cert2.to_dict(), cert3.to_dict()],
|
||||
'sni_container_refs': [self.sni_container_ref_1,
|
||||
self.sni_container_ref_2],
|
||||
'timeout_client_data': 1000,
|
||||
'timeout_member_connect': 2000,
|
||||
'timeout_member_data': 3000,
|
||||
@ -498,9 +508,11 @@ class TestUtils(base.TestCase):
|
||||
|
||||
@mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
|
||||
def test_lb_dict_to_provider_dict(self, mock_load_cert):
|
||||
mock_load_cert.return_value = {'tls_cert': 'cert 1',
|
||||
'sni_certs': ['cert 2', 'cert 3']}
|
||||
|
||||
cert1 = data_models.TLSContainer(certificate='cert 1')
|
||||
cert2 = data_models.TLSContainer(certificate='cert 2')
|
||||
cert3 = data_models.TLSContainer(certificate='cert 3')
|
||||
mock_load_cert.return_value = {'tls_cert': cert1,
|
||||
'sni_certs': [cert2, cert3]}
|
||||
test_lb_dict = {'name': 'lb1', 'project_id': self.project_id,
|
||||
'vip_subnet_id': self.subnet_id,
|
||||
'vip_port_id': self.port_id,
|
||||
@ -542,16 +554,22 @@ class TestUtils(base.TestCase):
|
||||
|
||||
@mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
|
||||
def test_db_listeners_to_provider_listeners(self, mock_load_cert):
|
||||
mock_load_cert.return_value = {'tls_cert': 'cert 1',
|
||||
'sni_certs': ['cert 2', 'cert 3']}
|
||||
cert1 = data_models.TLSContainer(certificate='cert 1')
|
||||
cert2 = data_models.TLSContainer(certificate='cert 2')
|
||||
cert3 = data_models.TLSContainer(certificate='cert 3')
|
||||
mock_load_cert.return_value = {'tls_cert': cert1,
|
||||
'sni_certs': [cert2, cert3]}
|
||||
provider_listeners = utils.db_listeners_to_provider_listeners(
|
||||
self.test_db_listeners)
|
||||
self.assertEqual(self.provider_listeners, provider_listeners)
|
||||
|
||||
@mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
|
||||
def test_listener_dict_to_provider_dict(self, mock_load_cert):
|
||||
mock_load_cert.return_value = {'tls_cert': 'cert 1',
|
||||
'sni_certs': ['cert 2', 'cert 3']}
|
||||
cert1 = data_models.TLSContainer(certificate='cert 1')
|
||||
cert2 = data_models.TLSContainer(certificate='cert 2')
|
||||
cert3 = data_models.TLSContainer(certificate='cert 3')
|
||||
mock_load_cert.return_value = {'tls_cert': cert1,
|
||||
'sni_certs': [cert2, cert3]}
|
||||
provider_listener = utils.listener_dict_to_provider_dict(
|
||||
self.test_listener1_dict)
|
||||
self.assertEqual(self.provider_listener1_dict, provider_listener)
|
||||
|
@ -219,6 +219,8 @@ Load balancer
|
||||
+-----------------+--------+-----------------------------------------------+
|
||||
| name | string | Human-readable name of the resource. |
|
||||
+-----------------+--------+-----------------------------------------------+
|
||||
|vip_qos_policy_id| string | The ID of the qos policy for the VIP. |
|
||||
+-----------------+--------+-----------------------------------------------+
|
||||
|
||||
The load balancer will be in the ``PENDING_UPDATE`` provisioning_status when
|
||||
it is passed to the driver. The driver will update the provisioning_status
|
||||
@ -332,61 +334,85 @@ Listener
|
||||
As of the writing of this specification the create listener object may
|
||||
contain the following:
|
||||
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| Name | Type | Description |
|
||||
+=======================+========+==========================================+
|
||||
| admin_state_up | bool | Admin state: True if up, False if down. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| connection_limit | int | The max number of connections permitted |
|
||||
| | | for this listener. Default is -1, which |
|
||||
| | | is infinite connections. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| default_pool | object | A `Pool object`_. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| default_pool_id | string | The ID of the pool used by the listener |
|
||||
| | | if no L7 policies match. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| default_tls_container | object | A pkcs12 format certicate and key. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| description | string | A human-readable description for the |
|
||||
| | | listener. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| insert_headers | dict | A dictionary of optional headers to |
|
||||
| | | insert into the request before it is sent|
|
||||
| | | to the backend member. See |
|
||||
| | | `Supported HTTP Header Insertions`_. |
|
||||
| | | Keys and values are specified as strings.|
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| l7policies | list | A list of `L7policy objects`_. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| listener_id | string | ID of listener to create. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| loadbalancer_id | string | ID of load balancer. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| name | string | Human-readable name of the listener. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| protocol | string | Protocol type: One of HTTP, HTTPS, TCP, |
|
||||
| | | or TERMINATED_HTTPS. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| protocol_port | int | Protocol port number. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| sni_containers | object | A pkcs12 format set of certificates. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| timeout_client_data | int | Frontend client inactivity timeout in |
|
||||
| | | milliseconds. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| timeout_member_connect| int | Backend member connection timeout in |
|
||||
| | | milliseconds. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| timeout_member_data | int | Backend member inactivity timeout in |
|
||||
| | | milliseconds. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| timeout_tcp_inspect | int | Time, in milliseconds, to wait for |
|
||||
| | | additional TCP packets for content |
|
||||
| | | inspection. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| Name | Type | Description |
|
||||
+============================+========+=====================================+
|
||||
| admin_state_up | bool | Admin state: True if up, False if |
|
||||
| | | down. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| connection_limit | int | The max number of connections |
|
||||
| | | permitted for this listener. Default|
|
||||
| | | is -1, which is infinite |
|
||||
| | | connections. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| default_pool | object | A `Pool object`_. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| default_pool_id | string | The ID of the pool used by the |
|
||||
| | | listener if no L7 policies match. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| default_tls_container_data | dict | A `TLS container`_ dict. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| default_tls_container_refs | string | The reference to the secrets |
|
||||
| | | container. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| description | string | A human-readable description for the|
|
||||
| | | listener. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| insert_headers | dict | A dictionary of optional headers to |
|
||||
| | | insert into the request before it is|
|
||||
| | | sent to the backend member. See |
|
||||
| | | `Supported HTTP Header Insertions`_.|
|
||||
| | | Keys and values are specified as |
|
||||
| | | strings. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| l7policies | list | A list of `L7policy objects`_. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| listener_id | string | ID of listener to create. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| loadbalancer_id | string | ID of load balancer. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| name | string | Human-readable name of the listener.|
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| protocol | string | Protocol type: One of HTTP, HTTPS, |
|
||||
| | | TCP, or TERMINATED_HTTPS. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| protocol_port | int | Protocol port number. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| sni_container_data | list | A list of `TLS container`_ dict. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| sni_container_refs | list | A list of references to the SNI |
|
||||
| | | secrets containers. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| timeout_client_data | int | Frontend client inactivity timeout |
|
||||
| | | in milliseconds. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| timeout_member_connect | int | Backend member connection timeout in|
|
||||
| | | milliseconds. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| timeout_member_data | int | Backend member inactivity timeout in|
|
||||
| | | milliseconds. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| timeout_tcp_inspect | int | Time, in milliseconds, to wait for |
|
||||
| | | additional TCP packets for content |
|
||||
| | | inspection. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
|
||||
.. _TLS container:
|
||||
|
||||
As of the writing of this specification the TLS container dictionary
|
||||
contains the following:
|
||||
|
||||
+---------------+--------+------------------------------------------------+
|
||||
| Key | Type | Description |
|
||||
+===============+========+================================================+
|
||||
| certificate | string | The PEM encoded certificate. |
|
||||
+---------------+--------+------------------------------------------------+
|
||||
| intermediates | List | A list of intermediate PEM certificates. |
|
||||
+---------------+--------+------------------------------------------------+
|
||||
| primary_cn | string | The primary common name of the certificate. |
|
||||
+---------------+--------+------------------------------------------------+
|
||||
| private_key | string | The PEM encoded private key. |
|
||||
+---------------+--------+------------------------------------------------+
|
||||
|
||||
.. _Supported HTTP Header Insertions:
|
||||
|
||||
@ -434,35 +460,57 @@ Listener
|
||||
As of the writing of this specification the update listener object may
|
||||
contain the following:
|
||||
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| Name | Type | Description |
|
||||
+=======================+========+==========================================+
|
||||
| admin_state_up | bool | Admin state: True if up, False if down. |
|
||||
+-----------------------+--------+----------+-------------------------------+
|
||||
| connection_limit | int | The max number of connections permitted |
|
||||
| | | for this listener. Default is -1, which |
|
||||
| | | is infinite connections. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| default_pool_id | string | The ID of the pool used by the listener |
|
||||
| | | if no L7 policies match. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| default_tls_container | object | A pkcs12 format certicate and key. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| description | string | A human-readable description for the |
|
||||
| | | listener. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| insert_headers | dict | A dictionary of optional headers to |
|
||||
| | | insert into the request before it is sent|
|
||||
| | | to the backend member. See |
|
||||
| | | `Supported HTTP Header Insertions`_. |
|
||||
| | | Keys and values are specified as strings.|
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| listener_id | string | ID of listener to update. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| name | string | Human-readable name of the listener. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| sni_containers | object | A pkcs12 format set of certificates. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| Name | Type | Description |
|
||||
+============================+========+=====================================+
|
||||
| admin_state_up | bool | Admin state: True if up, False if |
|
||||
| | | down. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| connection_limit | int | The max number of connections |
|
||||
| | | permitted for this listener. Default|
|
||||
| | | is -1, which is infinite |
|
||||
| | | connections. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| default_pool_id | string | The ID of the pool used by the |
|
||||
| | | listener if no L7 policies match. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| default_tls_container_data | dict | A `TLS container`_ dict. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| default_tls_container_refs | string | The reference to the secrets |
|
||||
| | | container. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| description | string | A human-readable description for |
|
||||
| | | the listener. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| insert_headers | dict | A dictionary of optional headers to |
|
||||
| | | insert into the request before it is|
|
||||
| | | sent to the backend member. See |
|
||||
| | | `Supported HTTP Header Insertions`_.|
|
||||
| | | Keys and values are specified as |
|
||||
| | | strings. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| listener_id | string | ID of listener to update. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| name | string | Human-readable name of the listener.|
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| sni_container_data | list | A list of `TLS container`_ dict. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| sni_container_refs | list | A list of references to the SNI |
|
||||
| | | secrets containers. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| timeout_client_data | int | Frontend client inactivity timeout |
|
||||
| | | in milliseconds. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| timeout_member_connect | int | Backend member connection timeout in|
|
||||
| | | milliseconds. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| timeout_member_data | int | Backend member inactivity timeout in|
|
||||
| | | milliseconds. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
| timeout_tcp_inspect | int | Time, in milliseconds, to wait for |
|
||||
| | | additional TCP packets for content |
|
||||
| | | inspection. |
|
||||
+----------------------------+--------+-------------------------------------+
|
||||
|
||||
The listener will be in the ``PENDING_UPDATE`` provisioning_status when
|
||||
it is passed to the driver. The driver will update the provisioning_status
|
||||
@ -761,6 +809,10 @@ Member
|
||||
+=======================+========+==========================================+
|
||||
| admin_state_up | bool | Admin state: True if up, False if down. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| backup | bool | Is the member a backup? Backup members |
|
||||
| | | only receive traffic when all non-backup |
|
||||
| | | members are down. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| member_id | string | ID of member to update. |
|
||||
+-----------------------+--------+------------------------------------------+
|
||||
| monitor_address | string | An alternate IP address used for health |
|
||||
|
Loading…
x
Reference in New Issue
Block a user