Remove v1 API and associated code
Includes some updates to docs and configs and related files to remove references to neutron-lbaas. Also remove handlers. Change-Id: I3082962841d3b645f3cbd1a6b41fc7fb28dcf7e6changes/07/656707/4
parent
1a87298ac7
commit
29d4340e9f
|
@ -1,13 +1,5 @@
|
|||
{
|
||||
"versions": [{
|
||||
"status": "DEPRECATED",
|
||||
"updated": "2014-12-11T00:00:00Z",
|
||||
"id": "v1",
|
||||
"links": [{
|
||||
"href": "http://10.21.21.53/load-balancer/v1",
|
||||
"rel": "self"
|
||||
}]
|
||||
}, {
|
||||
"status": "SUPPORTED",
|
||||
"updated": "2016-12-11T00:00:00Z",
|
||||
"id": "v2.0",
|
||||
|
|
|
@ -15,15 +15,10 @@ Supported API version
|
|||
|
||||
None
|
||||
|
||||
Deprecated API version
|
||||
|
||||
:doc:`v1/octaviaapi`
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
v2/index
|
||||
v1/octaviaapi
|
||||
|
||||
Octavia API minor releases are additive to the API major revision and share
|
||||
the same URL path. Minor revision changes to the API are called out in the API
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -270,15 +270,6 @@ function octavia_configure {
|
|||
iniset $OCTAVIA_CONF oslo_messaging rpc_thread_pool_size 2
|
||||
iniset $OCTAVIA_CONF oslo_messaging topic octavia_prov
|
||||
|
||||
# TODO(nmagnezi): Remove this when neutron-lbaas gets deprecated
|
||||
# Setting neutron request_poll_timeout
|
||||
iniset $NEUTRON_CONF octavia request_poll_timeout 3000
|
||||
if [[ "$WSGI_MODE" == "uwsgi" ]]; then
|
||||
iniadd $NEUTRON_CONF octavia base_url "$OCTAVIA_PROTOCOL://$SERVICE_HOST/$OCTAVIA_SERVICE_TYPE"
|
||||
else
|
||||
iniadd $NEUTRON_CONF octavia base_url "$OCTAVIA_PROTOCOL://$SERVICE_HOST:$OCTAVIA_PORT/"
|
||||
fi
|
||||
|
||||
# Uncomment other default options
|
||||
iniuncomment $OCTAVIA_CONF haproxy_amphora base_path
|
||||
iniuncomment $OCTAVIA_CONF haproxy_amphora base_cert_dir
|
||||
|
|
|
@ -90,11 +90,7 @@ GITREPO["octavia-lib"]=${OCTAVIA_LIB_REPO:-${GIT_BASE}/openstack/octavia-lib.git
|
|||
GITBRANCH["octavia-lib"]=${OCTAVIA_LIB_BRANCH:-master}
|
||||
GITDIR["octavia-lib"]=$DEST/octavia-lib
|
||||
|
||||
NEUTRON_LBAAS_DIR=$DEST/neutron-lbaas
|
||||
NEUTRON_LBAAS_CONF=$NEUTRON_CONF_DIR/neutron_lbaas.conf
|
||||
OCTAVIA_SERVICE_PROVIDER=${OCTAVIA_SERVICE_PROVIDER:-"LOADBALANCERV2:Octavia:neutron_lbaas.drivers.octavia.driver.OctaviaDriver:default"}
|
||||
NEUTRON_ANY=${NEUTRON_ANY:-"q-svc neutron-api"}
|
||||
LBAAS_V2=${LBAAS_V2:-"neutron-lbaasv2"}
|
||||
|
||||
# HA-deployment related settings
|
||||
OCTAVIA_USE_PREGENERATED_SSH_KEY=${OCTAVIA_USE_PREGENERATED_SSH_KEY:-"False"}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Tempest documentation build configuration file, created by
|
||||
# Octavia documentation build configuration file, created by
|
||||
# sphinx-quickstart on Tue May 21 17:43:32 2013.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing
|
||||
|
|
|
@ -72,8 +72,7 @@ Deployment
|
|||
2. Copy ``devstack/contrib/new-octavia-devstack.sh`` from this source
|
||||
repository onto that host.
|
||||
3. Run new-octavia-devstack.sh as root.
|
||||
4. Deploy loadbalancers, listeners, etc. as you would with any Neutron LBaaS v2
|
||||
enabled cloud.
|
||||
4. Deploy loadbalancers, listeners, etc.
|
||||
|
||||
|
||||
Running Octavia in production
|
||||
|
@ -125,7 +124,7 @@ For the purposes of this guide, we will therefore assume the following core
|
|||
components have already been set up for your production OpenStack environment:
|
||||
|
||||
* Nova
|
||||
* Neutron (with Neutron LBaaS v2)
|
||||
* Neutron
|
||||
* Glance
|
||||
* Barbican (if TLS offloading functionality is enabled)
|
||||
* Keystone
|
||||
|
@ -138,11 +137,8 @@ Production Deployment Walkthrough
|
|||
|
||||
Create Octavia User
|
||||
___________________
|
||||
By default Octavia will use the 'neutron' user for keystone authentication, and
|
||||
the admin user for interactions with all other services. However, it doesn't
|
||||
actually share neutron's database or otherwise access Neutron outside of
|
||||
Neutron's API, so a dedicated 'octavia' keystone user should generally be
|
||||
created for Octavia to use.
|
||||
By default Octavia will use the 'octavia' user for keystone authentication, and
|
||||
the admin user for interactions with all other services.
|
||||
|
||||
You must:
|
||||
|
||||
|
@ -225,14 +221,8 @@ Running multiple instances of the individual Octavia controller components on
|
|||
separate physical hosts is recommended in order to provide scalability and
|
||||
availability of the controller software.
|
||||
|
||||
One important security note: In 0.9 of Octavia, the Octavia API is designed to
|
||||
be consumed only by the Neutron-LBaaS v2 Octavia driver. As such, there is
|
||||
presently no authentication required to use the Octavia API, and therefore the
|
||||
Octavia API should only be accessible on trusted network segments
|
||||
(specifically, the segment that runs the neutron-services daemons.)
|
||||
|
||||
The Octavia controller presently consists of several components which may be
|
||||
split across several physical machines. For the 0.9 release of Octavia, the
|
||||
split across several physical machines. For the 4.0 release of Octavia, the
|
||||
important (and potentially separable) components are the controller worker,
|
||||
housekeeper, health manager and API controller. Please see the component
|
||||
diagrams elsewhere in this repository's documentation for detailed descriptions
|
||||
|
@ -253,7 +243,7 @@ components need access to outside resources:
|
|||
| housekeeper | Yes | Yes | No |
|
||||
+-------------------+------------+----------+----------------+
|
||||
|
||||
In addition to talking to each other via OSLO messaging, various controller
|
||||
In addition to talking to each other via Oslo messaging, various controller
|
||||
components must also communicate with other OpenStack components, like nova,
|
||||
neutron, barbican, etc. via their APIs.
|
||||
|
||||
|
@ -438,46 +428,22 @@ You must:
|
|||
* Make sure each Octavia controller component is started appropriately.
|
||||
|
||||
|
||||
Configuring Neutron LBaaS
|
||||
_________________________
|
||||
This is fairly straightforward. Neutron LBaaS needs to be directed to use the
|
||||
Octavia service provider. There should be a line like the following in
|
||||
``/etc/neutron/neutron_lbaas.conf`` file's ``[service providers]`` section:
|
||||
|
||||
::
|
||||
|
||||
service_provider = LOADBALANCERV2:Octavia:neutron_lbaas.drivers.octavia.driver.OctaviaDriver:default
|
||||
|
||||
In addition to the above you must add the octavia API ``base_url`` to the
|
||||
``[octavia]`` section of ``/etc/neutron/neutron.conf``. For example:
|
||||
|
||||
::
|
||||
|
||||
[octavia]
|
||||
base_url=http://127.0.0.1:9876
|
||||
|
||||
You must:
|
||||
|
||||
* Update ``/etc/neutron/neutron_lbaas.conf`` as described above.
|
||||
* Add the octavia API URL to ``/etc/neutron/neutron.conf``.
|
||||
|
||||
|
||||
Install Neutron-LBaaS v2 extension in Horizon
|
||||
Install Octavia extension in Horizon
|
||||
_____________________________________________
|
||||
This isn't strictly necessary for all cloud installations, however, if yours
|
||||
makes use of the Horizon GUI interface for tenants, it is probably also a good
|
||||
idea to make sure that it is configured with the Neutron-LBaaS v2 extension.
|
||||
idea to make sure that it is configured with the Octavia extension.
|
||||
|
||||
You may:
|
||||
|
||||
* Install the neutron-lbaasv2 GUI extension in Horizon
|
||||
* Install the octavia GUI extension in Horizon
|
||||
|
||||
|
||||
Test deployment
|
||||
_______________
|
||||
If all of the above instructions have been followed, it should now be possible
|
||||
to deploy load balancing services using the python neutronclient CLI,
|
||||
communicating with the neutron-lbaas v2 API.
|
||||
to deploy load balancing services using the OpenStack CLI,
|
||||
communicating with the Octavia v2 API.
|
||||
|
||||
Example:
|
||||
|
||||
|
|
|
@ -1,672 +0,0 @@
|
|||
..
|
||||
Copyright (c) 2016 IBM
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
===============================================================
|
||||
Basic Load Balancing Cookbook Using Neutron Client (deprecated)
|
||||
===============================================================
|
||||
|
||||
.. warning:: The neutron client used in this document is deprecated. We
|
||||
strongly encourage you to use the OpenStack Client and Octavia
|
||||
OpenStack Client plugin instead. This document is being maintained
|
||||
for deployments still using neutron-lbaas and the neutron client.
|
||||
|
||||
Introduction
|
||||
============
|
||||
This document contains several examples of using basic load balancing services
|
||||
as a tenant or "regular" cloud user.
|
||||
|
||||
For the purposes of this guide we assume that the neutron and barbican
|
||||
command-line interfaces are going to be used to configure all features of
|
||||
Neutron LBaaS with an Octavia back-end. In order to keep these examples short,
|
||||
we also assume that tasks not directly associated with deploying load balancing
|
||||
services have already been accomplished. This might include such things as
|
||||
deploying and configuring web servers, setting up Neutron networks, obtaining
|
||||
TLS certificates from a trusted provider, and so on. A description of the
|
||||
starting conditions is given in each example below.
|
||||
|
||||
Please also note that this guide assumes you are familiar with the specific
|
||||
load balancer terminology defined in the :doc:`../../reference/glossary`. For a
|
||||
description of load balancing itself and the Octavia project, please see:
|
||||
:doc:`../../reference/introduction`.
|
||||
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
Deploy a basic HTTP load balancer
|
||||
---------------------------------
|
||||
While this is technically the simplest complete load balancing solution that
|
||||
can be deployed, we recommend deploying HTTP load balancers with a health
|
||||
monitor to ensure back-end member availability. See
|
||||
:ref:`basic-lb-with-hm-neutron` below.
|
||||
|
||||
**Scenario description**:
|
||||
|
||||
* Back-end servers 192.0.2.10 and 192.0.2.11 on subnet *private-subnet* have
|
||||
been configured with an HTTP application on TCP port 80.
|
||||
* Subnet *public-subnet* is a shared external subnet created by the cloud
|
||||
operator which is reachable from the internet.
|
||||
* We want to configure a basic load balancer that is accessible from the
|
||||
internet, which distributes web requests to the back-end servers.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create load balancer *lb1* on subnet *public-subnet*.
|
||||
2. Create listener *listener1*.
|
||||
3. Create pool *pool1* as *listener1*'s default pool.
|
||||
4. Add members 192.0.2.10 and 192.0.2.11 on *private-subnet* to *pool1*.
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
neutron lbaas-loadbalancer-create --name lb1 public-subnet
|
||||
# Re-run the following until lb1 shows ACTIVE and ONLINE statuses:
|
||||
neutron lbaas-loadbalancer-show lb1
|
||||
neutron lbaas-listener-create --name listener1 --loadbalancer lb1 --protocol HTTP --protocol-port 80
|
||||
neutron lbaas-pool-create --name pool1 --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTP
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.10 --protocol-port 80 pool1
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.11 --protocol-port 80 pool1
|
||||
|
||||
|
||||
.. _basic-lb-with-hm-neutron:
|
||||
|
||||
Deploy a basic HTTP load balancer with a health monitor
|
||||
-------------------------------------------------------
|
||||
This is the simplest recommended load balancing solution for HTTP applications.
|
||||
This solution is appropriate for operators with provider networks that are not
|
||||
compatible with Neutron floating-ip functionality (such as IPv6 networks).
|
||||
However, if you need to retain control of the external IP through which a load
|
||||
balancer is accessible, even if the load balancer needs to be destroyed or
|
||||
recreated, it may be more appropriate to deploy your basic load balancer using
|
||||
a floating IP. See :ref:`basic-lb-with-hm-and-fip-neutron` below.
|
||||
|
||||
**Scenario description**:
|
||||
|
||||
* Back-end servers 192.0.2.10 and 192.0.2.11 on subnet *private-subnet* have
|
||||
been configured with an HTTP application on TCP port 80.
|
||||
* These back-end servers have been configured with a health check at the URL
|
||||
path "/healthcheck". See :ref:`http-heath-monitors-neutron` below.
|
||||
* Subnet *public-subnet* is a shared external subnet created by the cloud
|
||||
operator which is reachable from the internet.
|
||||
* We want to configure a basic load balancer that is accessible from the
|
||||
internet, which distributes web requests to the back-end servers, and which
|
||||
checks the "/healthcheck" path to ensure back-end member health.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create load balancer *lb1* on subnet *public-subnet*.
|
||||
2. Create listener *listener1*.
|
||||
3. Create pool *pool1* as *listener1*'s default pool.
|
||||
4. Create a health monitor on *pool1* which tests the "/healthcheck" path.
|
||||
5. Add members 192.0.2.10 and 192.0.2.11 on *private-subnet* to *pool1*.
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
neutron lbaas-loadbalancer-create --name lb1 public-subnet
|
||||
# Re-run the following until lb1 shows ACTIVE and ONLINE statuses:
|
||||
neutron lbaas-loadbalancer-show lb1
|
||||
neutron lbaas-listener-create --name listener1 --loadbalancer lb1 --protocol HTTP --protocol-port 80
|
||||
neutron lbaas-pool-create --name pool1 --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTP
|
||||
neutron lbaas-healthmonitor-create --delay 5 --max-retries 4 --timeout 10 --type HTTP --url_path /healthcheck --pool pool1
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.10 --protocol-port 80 pool1
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.11 --protocol-port 80 pool1
|
||||
|
||||
|
||||
.. _basic-lb-with-hm-and-fip-neutron:
|
||||
|
||||
Deploy a basic HTTP load balancer using a floating IP
|
||||
-----------------------------------------------------
|
||||
It can be beneficial to use a floating IP when setting up a load balancer's VIP
|
||||
in order to ensure you retain control of the IP that gets assigned as the
|
||||
floating IP in case the load balancer needs to be destroyed, moved, or
|
||||
recreated.
|
||||
|
||||
Note that this is not possible to do with IPv6 load balancers as floating IPs
|
||||
do not work with IPv6. Further, there is currently a bug in Neutron Distributed
|
||||
Virtual Routing (DVR) which prevents floating IPs from working correctly when
|
||||
DVR is in use. See: https://bugs.launchpad.net/neutron/+bug/1583694
|
||||
|
||||
**Scenario description**:
|
||||
|
||||
* Back-end servers 192.0.2.10 and 192.0.2.11 on subnet *private-subnet* have
|
||||
been configured with an HTTP application on TCP port 80.
|
||||
* These back-end servers have been configured with a health check at the URL
|
||||
path "/healthcheck". See :ref:`http-heath-monitors-neutron` below.
|
||||
* Neutron network *public* is a shared external network created by the cloud
|
||||
operator which is reachable from the internet.
|
||||
* We want to configure a basic load balancer that is accessible from the
|
||||
internet, which distributes web requests to the back-end servers, and which
|
||||
checks the "/healthcheck" path to ensure back-end member health. Further, we
|
||||
want to do this using a floating IP.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create load balancer *lb1* on subnet *private-subnet*.
|
||||
2. Create listener *listener1*.
|
||||
3. Create pool *pool1* as *listener1*'s default pool.
|
||||
4. Create a health monitor on *pool1* which tests the "/healthcheck" path.
|
||||
5. Add members 192.0.2.10 and 192.0.2.11 on *private-subnet* to *pool1*.
|
||||
6. Create a floating IP address on *public-subnet*.
|
||||
7. Associate this floating IP with the *lb1*'s VIP port.
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
neutron lbaas-loadbalancer-create --name lb1 private-subnet
|
||||
# Re-run the following until lb1 shows ACTIVE and ONLINE statuses:
|
||||
neutron lbaas-loadbalancer-show lb1
|
||||
neutron lbaas-listener-create --name listener1 --loadbalancer lb1 --protocol HTTP --protocol-port 80
|
||||
neutron lbaas-pool-create --name pool1 --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTP
|
||||
neutron lbaas-healthmonitor-create --delay 5 --max-retries 4 --timeout 10 --type HTTP --url_path /healthcheck --pool pool1
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.10 --protocol-port 80 pool1
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.11 --protocol-port 80 pool1
|
||||
neutron floatingip-create public
|
||||
# The following IDs should be visible in the output of previous commands
|
||||
neutron floatingip-associate <floating_ip_id> <load_balancer_vip_port_id>
|
||||
|
||||
|
||||
Deploy a basic HTTP load balancer with session persistence
|
||||
----------------------------------------------------------
|
||||
**Scenario description**:
|
||||
|
||||
* Back-end servers 192.0.2.10 and 192.0.2.11 on subnet *private-subnet* have
|
||||
been configured with an HTTP application on TCP port 80.
|
||||
* The application is written such that web clients should always be directed to
|
||||
the same back-end server throughout their web session, based on an
|
||||
application cookie inserted by the web application named 'PHPSESSIONID'.
|
||||
* These back-end servers have been configured with a health check at the URL
|
||||
path "/healthcheck". See :ref:`http-heath-monitors-neutron` below.
|
||||
* Subnet *public-subnet* is a shared external subnet created by the cloud
|
||||
operator which is reachable from the internet.
|
||||
* We want to configure a basic load balancer that is accessible from the
|
||||
internet, which distributes web requests to the back-end servers, persists
|
||||
sessions using the PHPSESSIONID as a key, and which checks the "/healthcheck"
|
||||
path to ensure back-end member health.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create load balancer *lb1* on subnet *public-subnet*.
|
||||
2. Create listener *listener1*.
|
||||
3. Create pool *pool1* as *listener1*'s default pool which defines session
|
||||
persistence on the 'PHPSESSIONID' cookie.
|
||||
4. Create a health monitor on *pool1* which tests the "/healthcheck" path.
|
||||
5. Add members 192.0.2.10 and 192.0.2.11 on *private-subnet* to *pool1*.
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
neutron lbaas-loadbalancer-create --name lb1 public-subnet
|
||||
# Re-run the following until lb1 shows ACTIVE and ONLINE statuses:
|
||||
neutron lbaas-loadbalancer-show lb1
|
||||
neutron lbaas-listener-create --name listener1 --loadbalancer lb1 --protocol HTTP --protocol-port 80
|
||||
neutron lbaas-pool-create --name pool1 --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTP --session-persistence type=APP_COOKIE,cookie_name=PHPSESSIONID
|
||||
neutron lbaas-healthmonitor-create --delay 5 --max-retries 4 --timeout 10 --type HTTP --url_path /healthcheck --pool pool1
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.10 --protocol-port 80 pool1
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.11 --protocol-port 80 pool1
|
||||
|
||||
|
||||
Deploy a TCP load balancer
|
||||
--------------------------
|
||||
This is generally suitable when load balancing a non-HTTP TCP-based service.
|
||||
|
||||
**Scenario description**:
|
||||
|
||||
* Back-end servers 192.0.2.10 and 192.0.2.11 on subnet *private-subnet* have
|
||||
been configured with an custom application on TCP port 23456
|
||||
* Subnet *public-subnet* is a shared external subnet created by the cloud
|
||||
operator which is reachable from the internet.
|
||||
* We want to configure a basic load balancer that is accessible from the
|
||||
internet, which distributes requests to the back-end servers.
|
||||
* We want to employ a TCP health check to ensure that the back-end servers are
|
||||
available.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create load balancer *lb1* on subnet *public-subnet*.
|
||||
2. Create listener *listener1*.
|
||||
3. Create pool *pool1* as *listener1*'s default pool.
|
||||
4. Create a health monitor on *pool1* which probes *pool1*'s members' TCP
|
||||
service port.
|
||||
5. Add members 192.0.2.10 and 192.0.2.11 on *private-subnet* to *pool1*.
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
neutron lbaas-loadbalancer-create --name lb1 public-subnet
|
||||
# Re-run the following until lb1 shows ACTIVE and ONLINE statuses:
|
||||
neutron lbaas-loadbalancer-show lb1
|
||||
neutron lbaas-listener-create --name listener1 --loadbalancer lb1 --protocol TCP --protocol-port 23456
|
||||
neutron lbaas-pool-create --name pool1 --lb-algorithm ROUND_ROBIN --listener listener1 --protocol TCP
|
||||
neutron lbaas-healthmonitor-create --delay 5 --max-retries 4 --timeout 10 --type TCP --pool pool1
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.10 --protocol-port 80 pool1
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.11 --protocol-port 80 pool1
|
||||
|
||||
|
||||
Deploy a non-terminated HTTPS load balancer
|
||||
-------------------------------------------
|
||||
A non-terminated HTTPS load balancer acts effectively like a generic TCP load
|
||||
balancer: The load balancer will forward the raw TCP traffic from the web
|
||||
client to the back-end servers without decrypting it. This means that the
|
||||
back-end servers themselves must be configured to terminate the HTTPS
|
||||
connection with the web clients, and in turn, the load balancer cannot insert
|
||||
headers into the HTTP session indicating the client IP address. (That is, to
|
||||
the back-end server, all web requests will appear to originate from the load
|
||||
balancer.) Also, advanced load balancer features (like Layer 7 functionality)
|
||||
cannot be used with non-terminated HTTPS.
|
||||
|
||||
**Scenario description**:
|
||||
|
||||
* Back-end servers 192.0.2.10 and 192.0.2.11 on subnet *private-subnet* have
|
||||
been configured with a TLS-encrypted web application on TCP port 443.
|
||||
* Subnet *public-subnet* is a shared external subnet created by the cloud
|
||||
operator which is reachable from the internet.
|
||||
* We want to configure a basic load balancer that is accessible from the
|
||||
internet, which distributes requests to the back-end servers.
|
||||
* We want to employ a TCP health check to ensure that the back-end servers are
|
||||
available.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create load balancer *lb1* on subnet *public-subnet*.
|
||||
2. Create listener *listener1*.
|
||||
3. Create pool *pool1* as *listener1*'s default pool.
|
||||
4. Create a health monitor on *pool1* which probes *pool1*'s members' TCP
|
||||
service port.
|
||||
5. Add members 192.0.2.10 and 192.0.2.11 on *private-subnet* to *pool1*.
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
neutron lbaas-loadbalancer-create --name lb1 public-subnet
|
||||
# Re-run the following until lb1 shows ACTIVE and ONLINE statuses:
|
||||
neutron lbaas-loadbalancer-show lb1
|
||||
neutron lbaas-listener-create --name listener1 --loadbalancer lb1 --protocol HTTPS --protocol-port 443
|
||||
neutron lbaas-pool-create --name pool1 --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTPS
|
||||
neutron lbaas-healthmonitor-create --delay 5 --max-retries 4 --timeout 10 --type TCP --pool pool1
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.10 --protocol-port 443 pool1
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.11 --protocol-port 443 pool1
|
||||
|
||||
|
||||
.. _basic-tls-terminated-listener-neutron:
|
||||
|
||||
Deploy a TLS-terminated HTTPS load balancer
|
||||
-------------------------------------------
|
||||
With a TLS-terminated HTTPS load balancer, web clients communicate with the
|
||||
load balancer over TLS protocols. The load balancer terminates the TLS session
|
||||
and forwards the decrypted requests to the back-end servers. By terminating the
|
||||
TLS session on the load balancer, we offload the CPU-intensive encryption work
|
||||
to the load balancer, and enable the possibility of using advanced load
|
||||
balancer features, like Layer 7 features and header manipulation.
|
||||
|
||||
**Scenario description**:
|
||||
|
||||
* Back-end servers 192.0.2.10 and 192.0.2.11 on subnet *private-subnet* have
|
||||
been configured with regular HTTP application on TCP port 80.
|
||||
* These back-end servers have been configured with a health check at the URL
|
||||
path "/healthcheck". See :ref:`http-heath-monitors-neutron` below.
|
||||
* Subnet *public-subnet* is a shared external subnet created by the cloud
|
||||
operator which is reachable from the internet.
|
||||
* A TLS certificate, key, and intermediate certificate chain for
|
||||
www.example.com have been obtained from an external certificate authority.
|
||||
These now exist in the files server.crt, server.key, and ca-chain.p7b in the
|
||||
current directory. The key and certificate are PEM-encoded, and the
|
||||
intermediate certificate chain is PKCS7 PEM encoded. The key is not encrypted
|
||||
with a passphrase.
|
||||
* The *admin* user on this cloud installation has keystone ID *admin_id*
|
||||
* We want to configure a TLS-terminated HTTPS load balancer that is accessible
|
||||
from the internet using the key and certificate mentioned above, which
|
||||
distributes requests to the back-end servers over the non-encrypted HTTP
|
||||
protocol.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create barbican *secret* resources for the certificate, key, and
|
||||
intermediate certificate chain. We will call these *cert1*, *key1*, and
|
||||
*intermediates1* respectively.
|
||||
2. Create a *secret container* resource combining all of the above. We will
|
||||
call this *tls_container1*.
|
||||
3. Grant the *admin* user access to all the *secret* and *secret container*
|
||||
barbican resources above.
|
||||
4. Create load balancer *lb1* on subnet *public-subnet*.
|
||||
5. Create listener *listener1* as a TERMINATED_HTTPS listener referencing
|
||||
*tls_container1* as its default TLS container.
|
||||
6. Create pool *pool1* as *listener1*'s default pool.
|
||||
7. Add members 192.0.2.10 and 192.0.2.11 on *private-subnet* to *pool1*.
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
openstack secret store --name='cert1' --payload-content-type='text/plain' --payload="$(cat server.crt)"
|
||||
openstack secret store --name='key1' --payload-content-type='text/plain' --payload="$(cat server.key)"
|
||||
openstack secret store --name='intermediates1' --payload-content-type='text/plain' --payload="$(cat ca-chain.p7b)"
|
||||
openstack secret container create --name='tls_container1' --type='certificate' --secret="certificate=$(openstack secret list | awk '/ cert1 / {print $2}')" --secret="private_key=$(openstack secret list | awk '/ key1 / {print $2}')" --secret="intermediates=$(openstack secret list | awk '/ intermediates1 / {print $2}')"
|
||||
neutron lbaas-loadbalancer-create --name lb1 public-subnet
|
||||
# Re-run the following until lb1 shows ACTIVE and ONLINE statuses:
|
||||
neutron lbaas-loadbalancer-show lb1
|
||||
neutron lbaas-listener-create --loadbalancer lb1 --protocol-port 443 --protocol TERMINATED_HTTPS --name listener1 --default-tls-container=$(openstack secret container list | awk '/ tls_container1 / {print $2}')
|
||||
neutron lbaas-pool-create --name pool1 --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTP
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.10 --protocol-port 80 pool1
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.11 --protocol-port 80 pool1
|
||||
|
||||
|
||||
Deploy a TLS-terminated HTTPS load balancer with SNI
|
||||
----------------------------------------------------
|
||||
This example is exactly like :ref:`basic-tls-terminated-listener-neutron`,
|
||||
except that we have multiple TLS certificates that we would like to use on
|
||||
the same listener using Server Name Indication (SNI) technology.
|
||||
|
||||
**Scenario description**:
|
||||
|
||||
* Back-end servers 192.0.2.10 and 192.0.2.11 on subnet *private-subnet* have
|
||||
been configured with regular HTTP application on TCP port 80.
|
||||
* These back-end servers have been configured with a health check at the URL
|
||||
path "/healthcheck". See :ref:`http-heath-monitors-neutron` below.
|
||||
* Subnet *public-subnet* is a shared external subnet created by the cloud
|
||||
operator which is reachable from the internet.
|
||||
* TLS certificates, keys, and intermediate certificate chains for
|
||||
www.example.com and www2.example.com have been obtained from an external
|
||||
certificate authority. These now exist in the files server.crt, server.key,
|
||||
ca-chain.p7b, server2.crt, server2-encrypted.key, and ca-chain2.p7b in the
|
||||
current directory. The keys and certificates are PEM-encoded, and the
|
||||
intermediate certificate chains are PKCS7 PEM encoded.
|
||||
* The key for www.example.com is not encrypted with a passphrase.
|
||||
* The key for www2.example.com is encrypted with the passphrase "abc123".
|
||||
* The *admin* user on this cloud installation has keystone ID *admin_id*
|
||||
* We want to configure a TLS-terminated HTTPS load balancer that is accessible
|
||||
from the internet using the keys and certificates mentioned above, which
|
||||
distributes requests to the back-end servers over the non-encrypted HTTP
|
||||
protocol.
|
||||
* If a web client connects that is not SNI capable, we want the load balancer
|
||||
to respond with the certificate for www.example.com.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create barbican *secret* resources for the certificates, keys, and
|
||||
intermediate certificate chains. We will call these *cert1*, *key1*,
|
||||
*intermediates1*, *cert2*, *key2* and *intermediates2* respectively.
|
||||
2. Create a barbican *secret* resource *passphrase2* for the passphrase for
|
||||
*key2*
|
||||
3. Create *secret container* resources combining the above appropriately. We
|
||||
will call these *tls_container1* and *tls_container2*.
|
||||
4. Grant the *admin* user access to all the *secret* and *secret container*
|
||||
barbican resources above.
|
||||
5. Create load balancer *lb1* on subnet *public-subnet*.
|
||||
6. Create listener *listener1* as a TERMINATED_HTTPS listener referencing
|
||||
*tls_container1* as its default TLS container, and referencing both
|
||||
*tls_container1* and *tls_container2* using SNI.
|
||||
7. Create pool *pool1* as *listener1*'s default pool.
|
||||
8. Add members 192.0.2.10 and 192.0.2.11 on *private-subnet* to *pool1*.
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
openstack secret store --name='cert1' --payload-content-type='text/plain' --payload="$(cat server.crt)"
|
||||
openstack secret store --name='key1' --payload-content-type='text/plain' --payload="$(cat server.key)"
|
||||
openstack secret store --name='intermediates1' --payload-content-type='text/plain' --payload="$(cat ca-chain.p7b)"
|
||||
openstack secret container create --name='tls_container1' --type='certificate' --secret="certificate=$(openstack secret list | awk '/ cert1 / {print $2}')" --secret="private_key=$(openstack secret list | awk '/ key1 / {print $2}')" --secret="intermediates=$(openstack secret list | awk '/ intermediates1 / {print $2}')"
|
||||
openstack secret store --name='cert2' --payload-content-type='text/plain' --payload="$(cat server2.crt)"
|
||||
openstack secret store --name='key2' --payload-content-type='text/plain' --payload="$(cat server2-encrypted.key)"
|
||||
openstack secret store --name='intermediates2' --payload-content-type='text/plain' --payload="$(cat ca-chain2.p7b)"
|
||||
openstack secret store --name='passphrase2' --payload-content-type='text/plain' --payload="abc123"
|
||||
openstack secret container create --name='tls_container2' --type='certificate' --secret="certificate=$(openstack secret list | awk '/ cert2 / {print $2}')" --secret="private_key=$(openstack secret list | awk '/ key2 / {print $2}')" --secret="intermediates=$(openstack secret list | awk '/ intermediates2 / {print $2}')" --secret="private_key_passphrase=$(openstack secret list | awk '/ passphrase2 / {print $2}')"
|
||||
neutron lbaas-loadbalancer-create --name lb1 public-subnet
|
||||
# Re-run the following until lb1 shows ACTIVE and ONLINE statuses:
|
||||
neutron lbaas-loadbalancer-show lb1
|
||||
neutron lbaas-listener-create --loadbalancer lb1 --protocol-port 443 --protocol TERMINATED_HTTPS --name listener1 --default-tls-container=$(openstack secret container list | awk '/ tls_container1 / {print $2}') --sni-container_refs $(openstack secret container list | awk '/ tls_container1 / {print $2}') $(openstack secret container list | awk '/ tls_container2 / {print $2}')
|
||||
neutron lbaas-pool-create --name pool1 --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTP
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.10 --protocol-port 80 pool1
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.11 --protocol-port 80 pool1
|
||||
|
||||
|
||||
Deploy HTTP and TLS-terminated HTTPS load balancing on the same IP and backend
|
||||
------------------------------------------------------------------------------
|
||||
This example is exactly like :ref:`basic-tls-terminated-listener-neutron`,
|
||||
except that we would like to have both an HTTP and TERMINATED_HTTPS listener
|
||||
that use the same back-end pool (and therefore, probably respond with the
|
||||
exact same content regardless of whether the web client uses the HTTP or HTTPS
|
||||
protocol to connect).
|
||||
|
||||
Please note that if you wish all HTTP requests to be redirected to HTTPS (so
|
||||
that requests are only served via HTTPS, and attempts to access content over
|
||||
HTTP just get redirected to the HTTPS listener), then please see `the example
|
||||
<l7-cookbook-neutron.html#redirect-http-to-https-n>`__ in the
|
||||
:doc:`l7-cookbook-neutron`.
|
||||
|
||||
**Scenario description**:
|
||||
|
||||
* Back-end servers 192.0.2.10 and 192.0.2.11 on subnet *private-subnet* have
|
||||
been configured with regular HTTP application on TCP port 80.
|
||||
* These back-end servers have been configured with a health check at the URL
|
||||
path "/healthcheck". See :ref:`http-heath-monitors-neutron` below.
|
||||
* Subnet *public-subnet* is a shared external subnet created by the cloud
|
||||
operator which is reachable from the internet.
|
||||
* A TLS certificate, key, and intermediate certificate chain for
|
||||
www.example.com have been obtained from an external certificate authority.
|
||||
These now exist in the files server.crt, server.key, and ca-chain.p7b in the
|
||||
current directory. The key and certificate are PEM-encoded, and the
|
||||
intermediate certificate chain is PKCS7 PEM encoded. The key is not encrypted
|
||||
with a passphrase.
|
||||
* The *admin* user on this cloud installation has keystone ID *admin_id*
|
||||
* We want to configure a TLS-terminated HTTPS load balancer that is accessible
|
||||
from the internet using the key and certificate mentioned above, which
|
||||
distributes requests to the back-end servers over the non-encrypted HTTP
|
||||
protocol.
|
||||
* We also want to configure a HTTP load balancer on the same IP address as
|
||||
the above which serves the exact same content (ie. forwards to the same
|
||||
back-end pool) as the TERMINATED_HTTPS listener.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create barbican *secret* resources for the certificate, key, and
|
||||
intermediate certificate chain. We will call these *cert1*, *key1*, and
|
||||
*intermediates1* respectively.
|
||||
2. Create a *secret container* resource combining all of the above. We will
|
||||
call this *tls_container1*.
|
||||
3. Grant the *admin* user access to all the *secret* and *secret container*
|
||||
barbican resources above.
|
||||
4. Create load balancer *lb1* on subnet *public-subnet*.
|
||||
5. Create listener *listener1* as a TERMINATED_HTTPS listener referencing
|
||||
*tls_container1* as its default TLS container.
|
||||
6. Create pool *pool1* as *listener1*'s default pool.
|
||||
7. Add members 192.0.2.10 and 192.0.2.11 on *private-subnet* to *pool1*.
|
||||
8. Create listener *listener2* as an HTTP listener with *pool1* as its
|
||||
default pool.
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
openstack secret store --name='cert1' --payload-content-type='text/plain' --payload="$(cat server.crt)"
|
||||
openstack secret store --name='key1' --payload-content-type='text/plain' --payload="$(cat server.key)"
|
||||
openstack secret store --name='intermediates1' --payload-content-type='text/plain' --payload="$(cat ca-chain.p7b)"
|
||||
openstack secret container create --name='tls_container1' --type='certificate' --secret="certificate=$(openstack secret list | awk '/ cert1 / {print $2}')" --secret="private_key=$(openstack secret list | awk '/ key1 / {print $2}')" --secret="intermediates=$(openstack secret list | awk '/ intermediates1 / {print $2}')"
|
||||
neutron lbaas-loadbalancer-create --name lb1 public-subnet
|
||||
# Re-run the following until lb1 shows ACTIVE and ONLINE statuses:
|
||||
neutron lbaas-loadbalancer-show lb1
|
||||
neutron lbaas-listener-create --loadbalancer lb1 --protocol-port 443 --protocol TERMINATED_HTTPS --name listener1 --default-tls-container=$(openstack secret container list | awk '/ tls_container1 / {print $2}')
|
||||
neutron lbaas-pool-create --name pool1 --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTP
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.10 --protocol-port 80 pool1
|
||||
neutron lbaas-member-create --subnet private-subnet --address 192.0.2.11 --protocol-port 80 pool1
|
||||
neutron lbaas-listener-create --name listener2 --loadbalancer lb1 --protocol HTTP --protocol-port 80 --default-pool pool1
|
||||
|
||||
|
||||
.. _heath-monitor-best-practices-neutron:
|
||||
|
||||
Heath Monitor Best Practices
|
||||
============================
|
||||
While it is possible to set up a listener without a health monitor, if a
|
||||
back-end pool member goes down, Octavia will not remove the failed server from
|
||||
the pool until a considerable time has passed. This can lead to service
|
||||
disruption for web clients. Because of this, we recommend always configuring
|
||||
production load balancers to use a health monitor.
|
||||
|
||||
The health monitor itself is a process that does periodic health checks on each
|
||||
back-end server to pre-emptively detect failed servers and temporarily pull
|
||||
them out of the pool. Since effective health monitors depend as much on
|
||||
back-end application server configuration as proper load balancer
|
||||
configuration, some additional discussion of best practices is warranted here.
|
||||
|
||||
See also: `Octavia API Reference <https://developer.openstack.org/api-ref/load-balancer/>`_
|
||||
|
||||
|
||||
Heath monitor options
|
||||
---------------------
|
||||
All of the health monitors Octavia supports have the following configurable
|
||||
options:
|
||||
|
||||
* ``delay``: Number of seconds to wait between health checks.
|
||||
* ``timeout``: Number of seconds to wait for any given health check to
|
||||
complete. ``timeout`` should always be smaller than ``delay``.
|
||||
* ``max-retries``: Number of subsequent health checks a given back-end
|
||||
server must fail before it is considered *down*, or that a failed back-end
|
||||
server must pass to be considered *up* again.
|
||||
|
||||
|
||||
.. _http-heath-monitors-neutron:
|
||||
|
||||
HTTP health monitors
|
||||
--------------------
|
||||
In general, the application-side component of HTTP health checks are a part of
|
||||
the web application being load balanced. By default, Octavia will probe the "/"
|
||||
path on the application server. However, in many applications this is not
|
||||
appropriate because the "/" path ends up being a cached page, or causes the
|
||||
application server to do more work than is necessary for a basic health check.
|
||||
|
||||
In addition to the above options, HTTP health monitors also have the following
|
||||
options:
|
||||
|
||||
* ``url_path``: Path part of the URL that should be retrieved from the back-end
|
||||
server. By default this is "/".
|
||||
* ``http_method``: HTTP method that should be used to retrieve the
|
||||
``url_path``. By default this is "GET".
|
||||
* ``expected_codes``: List of HTTP status codes that indicate an OK health
|
||||
check. By default this is just "200".
|
||||
|
||||
Please keep the following best practices in mind when writing the code that
|
||||
generates the health check in your web application:
|
||||
|
||||
* The health monitor ``url_path`` should not require authentication to load.
|
||||
* By default the health monitor ``url_path`` should return a HTTP 200 OK status
|
||||
code to indicate a healthy server unless you specify alternate
|
||||
``expected_codes``.
|
||||
* The health check should do enough internal checks to ensure the application
|
||||
is healthy and no more. This may mean ensuring database or other external
|
||||
storage connections are up and running, server load is acceptable, the site
|
||||
is not in maintenance mode, and other tests specific to your application.
|
||||
* The page generated by the health check should be very light weight:
|
||||
|
||||
* It should return in a sub-second interval.
|
||||
* It should not induce significant load on the application server.
|
||||
|
||||
* The page generated by the health check should never be cached, though the
|
||||
code running the health check may reference cached data. For example, you may
|
||||
find it useful to run a more extensive health check via cron and store the
|
||||
results of this to disk. The code generating the page at the health monitor
|
||||
``url_path`` would incorporate the results of this cron job in the tests it
|
||||
performs.
|
||||
* Since Octavia only cares about the HTTP status code returned, and since
|
||||
health checks are run so frequently, it may make sense to use the "HEAD" or
|
||||
"OPTIONS" HTTP methods to cut down on unnecessary processing of a whole page.
|
||||
|
||||
|
||||
Other heath monitors
|
||||
--------------------
|
||||
Other health monitor types include ``PING``, ``TCP``, ``HTTPS``, and
|
||||
``TLS-HELLO``.
|
||||
|
||||
``PING`` health monitors send periodic ICMP PING requests to the back-end
|
||||
servers. Obviously, your back-end servers must be configured to allow PINGs in
|
||||
order for these health checks to pass.
|
||||
|
||||
``TCP`` health monitors open a TCP connection to the back-end server's protocol
|
||||
port. Your custom TCP application should be written to respond OK to the load
|
||||
balancer connecting, opening a TCP connection, and closing it again after the
|
||||
TCP handshake without sending any data.
|
||||
|
||||
``HTTPS`` health monitors operate exactly like HTTP health monitors, but with
|
||||
ssl back-end servers. Unfortunately, this causes problems if the servers are
|
||||
performing client certificate validation, as HAProxy won't have a valid cert.
|
||||
In this case, using ``TLS-HELLO`` type monitoring is an alternative.
|
||||
|
||||
``TLS-HELLO`` health monitors simply ensure the back-end server responds to
|
||||
SSLv3 client hello messages. It will not check any other health metrics, like
|
||||
status code or body contents.
|
||||
|
||||
|
||||
Intermediate certificate chains
|
||||
===============================
|
||||
Some TLS certificates require you to install an intermediate certificate chain
|
||||
in order for web client browsers to trust the certificate. This chain can take
|
||||
several forms, and is a file provided by the organization from whom you
|
||||
obtained your TLS certificate.
|
||||
|
||||
PEM-encoded chains
|
||||
------------------
|
||||
The simplest form of the intermediate chain is a PEM-encoded text file that
|
||||
either contains a sequence of individually-encoded PEM certificates, or a PEM
|
||||
encoded PKCS7 block(s). If this is the type of intermediate chain you have been
|
||||
provided, the file will contain either ``-----BEGIN PKCS7-----`` or
|
||||
``-----BEGIN CERTIFICATE-----`` near the top of the file, and one or more
|
||||
blocks of 64-character lines of ASCII text (that will look like gobbedlygook to
|
||||
a human). These files are also typically named with a ``.crt`` or ``.pem``
|
||||
extension.
|
||||
|
||||
To upload this type of intermediates chain to barbican, run a command similar
|
||||
to the following (assuming "intermediates-chain.pem" is the name of the file):
|
||||
|
||||
::
|
||||
|
||||
openstack secret store --name='intermediates1' --payload-content-type='text/plain' --payload="$(cat intermediates-chain.pem)"
|
||||
|
||||
DER-encoded chains
|
||||
------------------
|
||||
If the intermediates chain provided to you is a file that contains what appears
|
||||
to be random binary data, it is likely that it is a PKCS7 chain in DER format.
|
||||
These files also may be named with a ``.p7b`` extension. In order to use this
|
||||
intermediates chain, you can either convert it to a series of PEM-encoded
|
||||
certificates with the following command:
|
||||
|
||||
::
|
||||
|
||||
openssl pkcs7 -in intermediates-chain.p7b -inform DER -print_certs -out intermediates-chain.pem
|
||||
|
||||
...or convert it into a PEM-encoded PKCS7 bundle with the following command:
|
||||
|
||||
::
|
||||
|
||||
openssl pkcs7 -in intermediates-chain.p7b -inform DER -outform PEM -out intermediates-chain.pem
|
||||
|
||||
...or simply upload the binary DER file to barbican without conversion:
|
||||
|
||||
::
|
||||
|
||||
openstack secret store --name='intermediates1' --payload-content-type='application/octet-stream' --payload-content-encoding='base64' --payload="$(cat intermediates-chain.p7b | base64)"
|
||||
|
||||
In any case, if the file is not a PKCS7 DER bundle, then either of the above
|
||||
two openssl commands will fail.
|
||||
|
||||
Further reading
|
||||
===============
|
||||
For examples of using Layer 7 features for more advanced load balancing, please
|
||||
see: :doc:`l7-cookbook-neutron`
|
|
@ -1,361 +0,0 @@
|
|||
..
|
||||
Copyright (c) 2016 IBM
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
==================================================
|
||||
Layer 7 Cookbook Using Neutron Client (deprecated)
|
||||
==================================================
|
||||
|
||||
.. warning:: The neutron client used in this document is deprecated. We
|
||||
strongly encourage you to use the OpenStack Client and Octavia
|
||||
OpenStack Client plugin instead. This document is being maintained
|
||||
for deployments still using neutron-lbaas and the neutron client.
|
||||
|
||||
Introduction
|
||||
============
|
||||
This document gives several examples of common L7 load balancer usage. For a
|
||||
description of L7 load balancing see: :doc:`l7`
|
||||
|
||||
For the purposes of this guide we assume that the neutron command-line
|
||||
interface is going to be used to configure all features of Neutron LBaaS with
|
||||
an Octavia back-end. Also, in order to keep these examples short, we assume
|
||||
that many non-L7 configuration tasks (such as deploying loadbalancers,
|
||||
listeners, pools, members, healthmonitors, etc.) have already been
|
||||
accomplished. A description of the starting conditions is given in each example
|
||||
below.
|
||||
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
.. _redirect-http-to-https-n:
|
||||
|
||||
Redirect *http://www.example.com/* to *https://www.example.com/*
|
||||
----------------------------------------------------------------
|
||||
**Scenario description**:
|
||||
|
||||
* Load balancer *lb1* has been set up with ``TERMINATED_HTTPS`` listener
|
||||
*tls_listener* on TCP port 443.
|
||||
* *tls_listener* has been populated with a default pool, members, etc.
|
||||
* *tls_listener* is available under the DNS name *https://www.example.com/*
|
||||
* We want any regular HTTP requests to TCP port 80 on *lb1* to be redirected
|
||||
to *tls_listener* on TCP port 443.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create listener *http_listener* as an HTTP listener on *lb1* port 80.
|
||||
2. Set up an L7 Policy *policy1* on *http_listener* with action
|
||||
``REDIRECT_TO_URL`` pointed at the URL *https://www.example.com/*
|
||||
3. Add an L7 Rule to *policy1* which matches all requests.
|
||||
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
neutron lbaas-listener-create --name http_listener --loadbalancer lb1 --protocol HTTP --protocol-port 80
|
||||
neutron lbaas-l7policy-create --action REDIRECT_TO_URL --redirect-url https://www.example.com/ --listener http_listener --name policy1
|
||||
neutron lbaas-l7rule-create --type PATH --compare-type STARTS_WITH --value / policy1
|
||||
|
||||
|
||||
.. _send-requests-to-static-pool-n:
|
||||
|
||||
Send requests starting with /js or /images to *static_pool*
|
||||
-----------------------------------------------------------
|
||||
**Scenario description**:
|
||||
|
||||
* Listener *listener1* on load balancer *lb1* is set up to send all requests to
|
||||
its default_pool *pool1*.
|
||||
* We are introducing static content servers 10.0.0.10 and 10.0.0.11 on subnet
|
||||
*private-subnet*, and want any HTTP requests with a URL that starts with
|
||||
either "/js" or "/images" to be sent to those two servers instead of *pool1*.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create pool *static_pool* on *lb1*.
|
||||
2. Populate *static_pool* with the new back-end members.
|
||||
3. Create L7 Policy *policy1* with action ``REDIRECT_TO_POOL`` pointed at
|
||||
*static_pool*.
|
||||
4. Create an L7 Rule on *policy1* which looks for "/js" at the start of
|
||||
the request path.
|
||||
5. Create L7 Policy *policy2* with action ``REDIRECT_TO_POOL`` pointed at
|
||||
*static_pool*.
|
||||
6. Create an L7 Rule on *policy2* which looks for "/images" at the start
|
||||
of the request path.
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
neutron lbaas-pool-create --name static_pool --lb-algorithm ROUND_ROBIN --loadbalancer lb1 --protocol HTTP
|
||||
neutron lbaas-member-create --subnet private-subnet --address 10.0.0.10 --protocol-port 80 static_pool
|
||||
neutron lbaas-member-create --subnet private-subnet --address 10.0.0.11 --protocol-port 80 static_pool
|
||||
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool static_pool --listener listener1 --name policy1
|
||||
neutron lbaas-l7rule-create --type PATH --compare-type STARTS_WITH --value /js policy1
|
||||
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool static_pool --listener listener1 --name policy2
|
||||
neutron lbaas-l7rule-create --type PATH --compare-type STARTS_WITH --value /images policy2
|
||||
|
||||
**Alternate solution** (using regular expressions):
|
||||
|
||||
1. Create pool *static_pool* on *lb1*.
|
||||
2. Populate *static_pool* with the new back-end members.
|
||||
3. Create L7 Policy *policy1* with action ``REDIRECT_TO_POOL`` pointed at
|
||||
*static_pool*.
|
||||
4. Create an L7 Rule on *policy1* which uses a regular expression to match
|
||||
either "/js" or "/images" at the start of the request path.
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
neutron lbaas-pool-create --name static_pool --lb-algorithm ROUND_ROBIN --loadbalancer lb1 --protocol HTTP
|
||||
neutron lbaas-member-create --subnet private-subnet --address 10.0.0.10 --protocol-port 80 static_pool
|
||||
neutron lbaas-member-create --subnet private-subnet --address 10.0.0.11 --protocol-port 80 static_pool
|
||||
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool static_pool --listener listener1 --name policy1
|
||||
neutron lbaas-l7rule-create --type PATH --compare-type REGEX --value '^/(js|images)' policy1
|
||||
|
||||
|
||||
Send requests for *http://www2.example.com/* to *pool2*
|
||||
-------------------------------------------------------
|
||||
**Scenario description**:
|
||||
|
||||
* Listener *listener1* on load balancer *lb1* is set up to send all requests to
|
||||
its default_pool *pool1*.
|
||||
* We have set up a new pool *pool2* on *lb1* and want any requests using the
|
||||
HTTP/1.1 hostname *www2.example.com* to be sent to *pool2* instead.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create L7 Policy *policy1* with action ``REDIRECT_TO_POOL`` pointed at
|
||||
*pool2*.
|
||||
2. Create an L7 Rule on *policy1* which matches the hostname
|
||||
*www2.example.com*.
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool pool2 --listener listener1 --name policy1
|
||||
neutron lbaas-l7rule-create --type HOST_NAME --compare-type EQUAL_TO --value www2.example.com policy1
|
||||
|
||||
|
||||
Send requests for *\*.example.com* to *pool2*
|
||||
---------------------------------------------
|
||||
**Scenario description**:
|
||||
|
||||
* Listener *listener1* on load balancer *lb1* is set up to send all requests to
|
||||
its default_pool *pool1*.
|
||||
* We have set up a new pool *pool2* on *lb1* and want any requests using any
|
||||
HTTP/1.1 hostname like *\*.example.com* to be sent to *pool2* instead.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create L7 Policy *policy1* with action ``REDIRECT_TO_POOL`` pointed at
|
||||
*pool2*.
|
||||
2. Create an L7 Rule on *policy1* which matches any hostname that ends with
|
||||
*example.com*.
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool pool2 --listener listener1 --name policy1
|
||||
neutron lbaas-l7rule-create --type HOST_NAME --compare-type ENDS_WITH --value example.com policy1
|
||||
|
||||
|
||||
Send unauthenticated users to *login_pool* (scenario 1)
|
||||
-------------------------------------------------------
|
||||
**Scenario description**:
|
||||
|
||||
* ``TERMINATED_HTTPS`` listener *listener1* on load balancer *lb1* is set up
|
||||
to send all requests to its default_pool *pool1*.
|
||||
* The site behind *listener1* requires all web users to authenticate, after
|
||||
which a browser cookie *auth_token* will be set.
|
||||
* When web users log out, or if the *auth_token* is invalid, the application
|
||||
servers in *pool1* clear the *auth_token*.
|
||||
* We want to introduce new secure authentication server 10.0.1.10 on Neutron
|
||||
subnet *secure_subnet* (a different Neutron subnet from the default
|
||||
application servers) which handles authenticating web users and sets the
|
||||
*auth_token*.
|
||||
|
||||
*Note:* Obviously, to have a more secure authentication system that is less
|
||||
vulnerable to attacks like XSS, the new secure authentication server will need
|
||||
to set session variables to which the default_pool servers will have access
|
||||
outside the data path with the web client. There may be other security concerns
|
||||
as well. This example is not meant to address how these are to be
|
||||
accomplished--it's mainly meant to show how L7 application routing can be done
|
||||
based on a browser cookie.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create pool *login_pool* on *lb1*.
|
||||
2. Add member 10.0.1.10 on *secure_subnet* to *login_pool*.
|
||||
3. Create L7 Policy *policy1* with action ``REDIRECT_TO_POOL`` pointed at
|
||||
*login_pool*.
|
||||
4. Create an L7 Rule on *policy1* which looks for browser cookie *auth_token*
|
||||
(with any value) and matches if it is *NOT* present.
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
neutron lbaas-pool-create --name login_pool --lb-algorithm ROUND_ROBIN --loadbalancer lb1 --protocol HTTP
|
||||
neutron lbaas-member-create --subnet secure_subnet --address 10.0.1.10 --protocol-port 80 login_pool
|
||||
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool login_pool --listener listener1 --name policy1
|
||||
neutron lbaas-l7rule-create --type COOKIE --key auth_token --compare-type REGEX --value '.*' --invert policy1
|
||||
|
||||
|
||||
Send unauthenticated users to *login_pool* (scenario 2)
|
||||
--------------------------------------------------------
|
||||
**Scenario description**:
|
||||
|
||||
* ``TERMINATED_HTTPS`` listener *listener1* on load balancer *lb1* is set up
|
||||
to send all requests to its default_pool *pool1*.
|
||||
* The site behind *listener1* requires all web users to authenticate, after
|
||||
which a browser cookie *auth_token* will be set.
|
||||
* When web users log out, or if the *auth_token* is invalid, the application
|
||||
servers in *pool1* set *auth_token* to the literal string "INVALID".
|
||||
* We want to introduce new secure authentication server 10.0.1.10 on Neutron
|
||||
subnet *secure_subnet* (a different Neutron subnet from the default
|
||||
application servers) which handles authenticating web users and sets the
|
||||
*auth_token*.
|
||||
|
||||
*Note:* Obviously, to have a more secure authentication system that is less
|
||||
vulnerable to attacks like XSS, the new secure authentication server will need
|
||||
to set session variables to which the default_pool servers will have access
|
||||
outside the data path with the web client. There may be other security concerns
|
||||
as well. This example is not meant to address how these are to be
|
||||
accomplished-- it's mainly meant to show how L7 application routing can be done
|
||||
based on a browser cookie.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create pool *login_pool* on *lb1*.
|
||||
2. Add member 10.0.1.10 on *secure_subnet* to *login_pool*.
|
||||
3. Create L7 Policy *policy1* with action ``REDIRECT_TO_POOL`` pointed at
|
||||
*login_pool*.
|
||||
4. Create an L7 Rule on *policy1* which looks for browser cookie *auth_token*
|
||||
(with any value) and matches if it is *NOT* present.
|
||||
5. Create L7 Policy *policy2* with action ``REDIRECT_TO_POOL`` pointed at
|
||||
*login_pool*.
|
||||
6. Create an L7 Rule on *policy2* which looks for browser cookie *auth_token*
|
||||
and matches if it is equal to the literal string "INVALID".
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
neutron lbaas-pool-create --name login_pool --lb-algorithm ROUND_ROBIN --loadbalancer lb1 --protocol HTTP
|
||||
neutron lbaas-member-create --subnet secure_subnet --address 10.0.1.10 --protocol-port 80 login_pool
|
||||
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool login_pool --listener listener1 --name policy1
|
||||
neutron lbaas-l7rule-create --type COOKIE --key auth_token --compare-type REGEX --value '.*' --invert policy1
|
||||
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool login_pool --listener listener1 --name policy2
|
||||
neutron lbaas-l7rule-create --type COOKIE --key auth_token --compare-type EQUAL_TO --value INVALID policy2
|
||||
|
||||
|
||||
Send requests for *http://api.example.com/api* to *api_pool*
|
||||
------------------------------------------------------------
|
||||
**Scenario description**:
|
||||
|
||||
* Listener *listener1* on load balancer *lb1* is set up to send all requests
|
||||
to its default_pool *pool1*.
|
||||
* We have created pool *api_pool* on *lb1*, however, for legacy business logic
|
||||
reasons, we only want requests sent to this pool if they match the hostname
|
||||
*api.example.com* AND the request path starts with */api*.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create L7 Policy *policy1* with action ``REDIRECT_TO_POOL`` pointed at
|
||||
*api_pool*.
|
||||
2. Create an L7 Rule on *policy1* which matches the hostname *api.example.com*.
|
||||
3. Create an L7 Rule on *policy1* which matches */api* at the start of the
|
||||
request path. (This rule will be logically ANDed with the previous rule.)
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool api_pool --listener listener1 --name policy1
|
||||
neutron lbaas-l7rule-create --type HOST_NAME --compare-type EQUAL_TO --value api.example.com policy1
|
||||
neutron lbaas-l7rule-create --type PATH --compare-type STARTS_WITH --value /api policy1
|
||||
|
||||
|
||||
Set up A/B testing on an existing production site using a cookie
|
||||
----------------------------------------------------------------
|
||||
**Scenario description**:
|
||||
|
||||
* Listener *listener1* on load balancer *lb1* is a production site set up as
|
||||
described under :ref:`send-requests-to-static-pool-n` (alternate solution)
|
||||
above. Specifically:
|
||||
|
||||
* HTTP requests with a URL that starts with either "/js" or "/images" are
|
||||
sent to pool *static_pool*.
|
||||
* All other requests are sent to *listener1's* default_pool *pool1*.
|
||||
|
||||
* We are introducing a "B" version of the production site, complete with its
|
||||
own default_pool and static_pool. We will call these *pool_B* and
|
||||
*static_pool_B* respectively.
|
||||
* The *pool_B* members should be 10.0.0.50 and 10.0.0.51, and the
|
||||
*static_pool_B* members should be 10.0.0.100 and 10.0.0.101 on subnet
|
||||
*private-subnet*.
|
||||
* Web clients which should be routed to the "B" version of the site get a
|
||||
cookie set by the member servers in *pool1*. This cookie is called
|
||||
"site_version" and should have the value "B".
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Create pool *pool_B* on *lb1*.
|
||||
2. Populate *pool_B* with its new back-end members.
|
||||
3. Create pool *static_pool_B* on *lb1*.
|
||||
4. Populate *static_pool_B* with its new back-end members.
|
||||
5. Create L7 Policy *policy2* with action ``REDIRECT_TO_POOL`` pointed at
|
||||
*static_pool_B*. This should be inserted at position 1.
|
||||
6. Create an L7 Rule on *policy2* which uses a regular expression to match
|
||||
either "/js" or "/images" at the start of the request path.
|
||||
7. Create an L7 Rule on *policy2* which matches the cookie "site_version" to
|
||||
the exact string "B".
|
||||
8. Create L7 Policy *policy3* with action ``REDIRECT_TO_POOL`` pointed at
|
||||
*pool_B*. This should be inserted at position 2.
|
||||
9. Create an L7 Rule on *policy3* which matches the cookie "site_version" to
|
||||
the exact string "B".
|
||||
|
||||
*A word about L7 Policy position*: Since L7 Policies are evaluated in order
|
||||
according to their position parameter, and since the first L7 Policy whose L7
|
||||
Rules all evaluate to True is the one whose action is followed, it is important
|
||||
that L7 Policies with the most specific rules get evaluated first.
|
||||
|
||||
For example, in this solution, if *policy3* were to appear in the listener's L7
|
||||
Policy list before *policy2* (that is, if *policy3* were to have a lower
|
||||
position number than *policy2*), then if a web client were to request the URL
|
||||
http://www.example.com/images/a.jpg with the cookie "site_version:B", then
|
||||
*policy3* would match, and the load balancer would send the request to
|
||||
*pool_B*. From the scenario description, this request clearly was meant to be
|
||||
sent to *static_pool_B*, which is why *policy2* needs to be evaluated before
|
||||
*policy3*.
|
||||
|
||||
**CLI commands**:
|
||||
|
||||
::
|
||||
|
||||
neutron lbaas-pool-create --name pool_B --lb-algorithm ROUND_ROBIN --loadbalancer lb1 --protocol HTTP
|
||||
neutron lbaas-member-create --subnet private-subnet --address 10.0.0.50 --protocol-port 80 pool_B
|
||||
neutron lbaas-member-create --subnet private-subnet --address 10.0.0.51 --protocol-port 80 pool_B
|
||||
neutron lbaas-pool-create --name static_pool_B --lb-algorithm ROUND_ROBIN --loadbalancer lb1 --protocol HTTP
|
||||
neutron lbaas-member-create --subnet private-subnet --address 10.0.0.100 --protocol-port 80 static_pool_B
|
||||
neutron lbaas-member-create --subnet private-subnet --address 10.0.0.101 --protocol-port 80 static_pool_B
|
||||
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool static_pool_B --listener listener1 --name policy2 --position 1
|
||||
neutron lbaas-l7rule-create --type PATH --compare-type REGEX --value '^/(js|images)' policy2
|
||||
neutron lbaas-l7rule-create --type COOKIE --key site_version --compare-type EQUAL_TO --value B policy2
|
||||
neutron lbaas-l7policy-create --action REDIRECT_TO_POOL --redirect-pool pool_B --listener listener1 --name policy3 --position 2
|
||||
neutron lbaas-l7rule-create --type COOKIE --key site_version --compare-type EQUAL_TO --value B policy3
|
|
@ -10,8 +10,6 @@ Cookbooks
|
|||
|
||||
guides/basic-cookbook
|
||||
guides/l7-cookbook
|
||||
guides/basic-cookbook-neutron
|
||||
guides/l7-cookbook-neutron
|
||||
|
||||
Guides
|
||||
======
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
[api_settings]
|
||||
# bind_host = 127.0.0.1
|
||||
# bind_port = 9876
|
||||
# api_handler = queue_producer
|
||||
|
||||
# How should authentication be handled (keystone, noauth)
|
||||
# auth_strategy = keystone
|
||||
|
@ -33,10 +32,6 @@
|
|||
# api_base_uri = http://localhost:9876
|
||||
# api_base_uri =
|
||||
|
||||
# Enable/disable exposing API endpoints. By default, both v1 and v2 are enabled.
|
||||
# api_v1_enabled = True
|
||||
# api_v2_enabled = True
|
||||
|
||||
# Enable/disable ability for users to create TLS Terminated listeners
|
||||
# allow_tls_terminated_listeners = True
|
||||
|
||||
|
@ -95,14 +90,6 @@
|
|||
# health_update_driver = health_db
|
||||
# stats_update_driver = stats_db
|
||||
|
||||
# EventStreamer options are
|
||||
# queue_event_streamer,
|
||||
# noop_event_streamer
|
||||
# event_streamer_driver = noop_event_streamer
|
||||
|
||||
# Enable provisioning status sync with neutron db
|
||||
# sync_provisioning_status = False
|
||||
|
||||
[keystone_authtoken]
|
||||
# This group of config options are imported from keystone middleware. Thus the
|
||||
# option names should match the names declared in the middleware.
|
||||
|
@ -285,17 +272,6 @@
|
|||
# Topic (i.e. Queue) Name
|
||||
# topic = octavia_prov
|
||||
|
||||
# Topic for octavia's events sent to a queue
|
||||
# event_stream_topic = neutron_lbaas_event
|
||||
|
||||
# Transport URL to use for the neutron-lbaas synchronization event stream
|
||||
# when neutron and octavia have separate queues.
|
||||
# For Single Host, specify one full transport URL:
|
||||
# event_stream_transport_url = rabbit://<user>:<pass>@127.0.0.1:5672/<vhost>
|
||||
# For HA, specify queue nodes in cluster, comma delimited:
|
||||
# event_stream_transport_url = rabbit://<user>:<pass>@server01,<user>:<pass>@server02/<vhost>
|
||||
# event_stream_transport_url =
|
||||
|
||||
[house_keeping]
|
||||
# Interval in seconds to initiate spare amphora checks
|
||||
# spare_check_interval = 30
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
|
@ -1,67 +0,0 @@
|
|||
# Copyright 2014 Rackspace
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import abc
|
||||
|
||||
import six
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class BaseObjectHandler(object):
|
||||
"""Base class for any object handler."""
|
||||
@abc.abstractmethod
|
||||
def create(self, model_id):
|
||||
"""Begins process of actually creating data_model."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def update(self, model_id, updated_dict):
|
||||
"""Begins process of actually updating data_model."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def delete(self, model_id):
|
||||
"""Begins process of actually deleting data_model."""
|
||||
pass
|
||||
|
||||
|
||||
class NotImplementedObjectHandler(BaseObjectHandler):
|
||||
"""Default Object Handler to force implementation of subclasses.
|
||||
|
||||
Helper class to make any subclass of AbstractHandler explode if it
|
||||
is missing any of the required object managers.
|
||||
"""
|
||||
@staticmethod
|
||||
def update(model_id, updated_dict):
|
||||
raise NotImplementedError()
|
||||
|
||||
@staticmethod
|
||||
def delete(model_id):
|
||||
raise NotImplementedError()
|
||||
|
||||
@staticmethod
|
||||
def create(model_id):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class BaseHandler(object):
|
||||
"""Base class for all handlers."""
|
||||
load_balancer = NotImplementedObjectHandler()
|
||||
listener = NotImplementedObjectHandler()
|
||||
pool = NotImplementedObjectHandler()
|
||||
health_monitor = NotImplementedObjectHandler()
|
||||
member = NotImplementedObjectHandler()
|
||||
l7policy = NotImplementedObjectHandler()
|
||||
l7rule = NotImplementedObjectHandler()
|
|
@ -1,11 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
|
@ -1,478 +0,0 @@
|
|||
# Copyright 2014 Rackspace
|
||||
# Copyright 2016 Blue Box, an IBM Company
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
This is just a handler that will simulate successful operations a controller
|
||||
should perform. There is nothing useful about this other than database
|
||||
entity status management.
|
||||
"""
|
||||
|
||||
import threading
|
||||
import time
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
from octavia.api.handlers import abstract_handler
|
||||
from octavia.common import constants
|
||||
from octavia.common import data_models
|
||||
from octavia.db import api as db_api
|
||||
import octavia.db.repositories as repos
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
ASYNC_TIME = 1
|
||||
|
||||
|
||||
def validate_input(expected, actual):
|
||||
if not isinstance(actual, expected):
|
||||
raise InvalidHandlerInputObject(obj_type=actual.__class__)
|
||||
|
||||
|
||||
def simulate_controller(data_model, delete=False, update=False, create=False,
|
||||
batch_update=False):
|
||||
"""Simulates a successful controller operator for a data model.
|
||||
|
||||
:param data_model: data model to simulate controller operation
|
||||
:param delete: deletes from the database
|
||||
"""
|
||||
repo = repos.Repositories()
|
||||
|
||||
def member_controller(member, delete=False, update=False, create=False,
|
||||
batch_update=False):
|
||||
time.sleep(ASYNC_TIME)
|
||||
LOG.info("Simulating controller operation for member...")
|
||||
|
||||
db_mem = None
|
||||
if delete:
|
||||
db_mem = repo.member.get(db_api.get_session(), id=member.id)
|
||||
repo.member.delete(db_api.get_session(), id=member.id)
|
||||
elif update:
|
||||
db_mem = repo.member.get(db_api.get_session(), id=member.id)
|
||||
member_dict = member.to_dict()
|
||||
member_dict['operating_status'] = db_mem.operating_status
|
||||
repo.member.update(db_api.get_session(), member.id, **member_dict)
|
||||
elif create:
|
||||
repo.member.update(db_api.get_session(), member.id,
|
||||
operating_status=constants.ONLINE)
|
||||
elif batch_update:
|
||||
members = member
|
||||
for m in members:
|
||||
repo.member.update(db_api.get_session(), m.id,
|
||||
operating_status=constants.ONLINE)
|
||||
listeners = []
|
||||
if db_mem:
|
||||
for listener in db_mem.pool.listeners:
|
||||
if listener not in listeners:
|
||||
listeners.append(listener)
|
||||
if member.pool.listeners:
|
||||
for listener in member.pool.listeners:
|
||||
if listener not in listeners:
|
||||
listeners.append(listener)
|
||||
if listeners:
|
||||
for listener in listeners:
|
||||
repo.listener.update(db_api.get_session(), listener.id,
|
||||
operating_status=constants.ONLINE,
|
||||
provisioning_status=constants.ACTIVE)
|
||||
repo.load_balancer.update(db_api.get_session(),
|
||||
member.pool.load_balancer.id,
|
||||
operating_status=constants.ONLINE,
|
||||
provisioning_status=constants.ACTIVE)
|
||||
LOG.info("Simulated Controller Handler Thread Complete")
|
||||
|
||||
def l7policy_controller(l7policy, delete=False, update=False,
|
||||
create=False):
|
||||
time.sleep(ASYNC_TIME)
|
||||
LOG.info("Simulating controller operation for l7policy...")
|
||||
|
||||
db_l7policy = None
|
||||
if delete:
|
||||
db_l7policy = repo.l7policy.get(db_api.get_session(),
|
||||
id=l7policy.id)
|
||||
repo.l7policy.delete(db_api.get_session(), id=l7policy.id)
|
||||
elif update:
|
||||
db_l7policy = repo.l7policy.get(db_api.get_session(),
|
||||
id=l7policy.id)
|
||||
l7policy_dict = l7policy.to_dict()
|
||||
repo.l7policy.update(db_api.get_session(), l7policy.id,
|
||||
**l7policy_dict)
|
||||
elif create:
|
||||
db_l7policy = repo.l7policy.create(db_api.get_session(),
|
||||
**l7policy.to_dict())
|
||||
if db_l7policy.listener:
|
||||
repo.listener.update(db_api.get_session(), db_l7policy.listener.id,
|
||||
operating_status=constants.ONLINE,
|
||||
provisioning_status=constants.ACTIVE)
|
||||
repo.load_balancer.update(db_api.get_session(),
|
||||
db_l7policy.listener.load_balancer.id,
|
||||
operating_status=constants.ONLINE,
|
||||
provisioning_status=constants.ACTIVE)
|
||||
LOG.info("Simulated Controller Handler Thread Complete")
|
||||
|
||||
def l7rule_controller(l7rule, delete=False, update=False, create=False):
|
||||
time.sleep(ASYNC_TIME)
|
||||
LOG.info("Simulating controller operation for l7rule...")
|
||||
|
||||
db_l7rule = None
|
||||
if delete:
|
||||
db_l7rule = repo.l7rule.get(db_api.get_session(), id=l7rule.id)
|
||||
repo.l7rule.delete(db_api.get_session(), id=l7rule.id)
|
||||
elif update:
|
||||
db_l7rule = repo.l7rule.get(db_api.get_session(), id=l7rule.id)
|
||||
l7rule_dict = l7rule.to_dict()
|
||||
repo.l7rule.update(db_api.get_session(), l7rule.id, **l7rule_dict)
|
||||
elif create:
|
||||
l7rule_dict = l7rule.to_dict()
|
||||
db_l7rule = repo.l7rule.create(db_api.get_session(), **l7rule_dict)
|
||||
if db_l7rule.l7policy.listener:
|
||||
listener = db_l7rule.l7policy.listener
|
||||
repo.listener.update(db_api.get_session(), listener.id,
|
||||
operating_status=constants.ONLINE,
|
||||
provisioning_status=constants.ACTIVE)
|
||||
repo.load_balancer.update(db_api.get_session(),
|
||||
listener.load_balancer.id,
|
||||
operating_status=constants.ONLINE,
|
||||
provisioning_status=constants.ACTIVE)
|
||||
LOG.info("Simulated Controller Handler Thread Complete")
|
||||
|
||||
def health_monitor_controller(health_monitor, delete=False, update=False,
|
||||
create=False):
|
||||
time.sleep(ASYNC_TIME)
|
||||
LOG.info("Simulating controller operation for health monitor...")
|
||||
|
||||
db_hm = None
|
||||
if delete:
|
||||
db_hm = repo.health_monitor.get(db_api.get_session(),
|
||||
pool_id=health_monitor.pool.id)
|
||||
repo.health_monitor.delete(db_api.get_session(),
|
||||
pool_id=health_monitor.pool.id)
|
||||
elif update:
|
||||
db_hm = repo.health_monitor.get(db_api.get_session(),
|
||||
pool_id=health_monitor.pool_id)
|
||||
hm_dict = health_monitor.to_dict()
|
||||
hm_dict['operating_status'] = db_hm.operating_status()
|
||||
repo.health_monitor.update(db_api.get_session(), **hm_dict)
|
||||
elif create:
|
||||
repo.pool.update(db_api.get_session(), health_monitor.pool_id,
|
||||
operating_status=constants.ONLINE)
|
||||
listeners = []
|
||||
if db_hm:
|
||||
for listener in db_hm.pool.listeners:
|
||||
if listener not in listeners:
|
||||
listeners.append(listener)
|
||||
if health_monitor.pool.listeners:
|
||||
for listener in health_monitor.pool.listeners:
|
||||
if listener not in listeners:
|
||||
listeners.append(listener)
|
||||
if listeners:
|
||||
for listener in listeners:
|
||||
repo.test_and_set_lb_and_listener_prov_status(
|
||||
db_api.get_session(),
|
||||
health_monitor.pool.load_balancer.id,
|
||||
listener.id, constants.ACTIVE,
|
||||
constants.ACTIVE)
|
||||
repo.listener.update(db_api.get_session(),
|
||||
listener.id,
|
||||
operating_status=constants.ONLINE,
|
||||
provisioning_status=constants.ACTIVE)
|
||||
repo.load_balancer.update(
|
||||
db_api.get_session(),
|
||||
health_monitor.pool.load_balancer.id,
|
||||
operating_status=constants.ONLINE,
|
||||
provisioning_status=constants.ACTIVE)
|
||||
LOG.info("Simulated Controller Handler Thread Complete")
|
||||
|
||||
def pool_controller(pool, delete=False, update=False, create=False):
|
||||
time.sleep(ASYNC_TIME)
|
||||
LOG.info("Simulating controller operation for pool...")
|
||||
|
||||
db_pool = None
|
||||
if delete:
|
||||
db_pool = repo.pool.get(db_api.get_session(), id=pool.id)
|
||||
repo.pool.delete(db_api.get_session(), id=pool.id)
|
||||
elif update:
|
||||
db_pool = repo.pool.get(db_api.get_session(), id=pool.id |