Browse Source

Add oslo middleware healthcheck to Octavia API

healthcheck middleware adds a /healthcheck url that allows
unauthenticated access to provide a simple check when running
octavia-api behind a load balancer

https://docs.openstack.org/oslo.middleware/latest/reference/healthcheck_plugins.html

Co-authored-by: Michael Johnson <johnsomor@gmail.com>
Change-Id: I10db6226750f7b7c703067d2ab82eea3a9875112
changes/27/711127/11
Sam Morrison 2 years ago
committed by Michael Johnson
parent
commit
18020e6c88
  1. 599
      doc/source/admin/healthcheck.rst
  2. 1
      doc/source/admin/index.rst
  3. 21
      etc/octavia.conf
  4. 6
      lower-constraints.txt
  5. 9
      octavia/api/app.py
  6. 47
      octavia/api/healthcheck/healthcheck_plugins.py
  7. 24
      octavia/api/root_controller.py
  8. 15
      octavia/api/v2/controllers/amphora.py
  9. 12
      octavia/api/v2/controllers/availability_zone_profiles.py
  10. 12
      octavia/api/v2/controllers/availability_zones.py
  11. 9
      octavia/api/v2/controllers/base.py
  12. 12
      octavia/api/v2/controllers/flavor_profiles.py
  13. 12
      octavia/api/v2/controllers/flavors.py
  14. 12
      octavia/api/v2/controllers/health_monitor.py
  15. 17
      octavia/api/v2/controllers/l7policy.py
  16. 12
      octavia/api/v2/controllers/l7rule.py
  17. 19
      octavia/api/v2/controllers/listener.py
  18. 21
      octavia/api/v2/controllers/load_balancer.py
  19. 14
      octavia/api/v2/controllers/member.py
  20. 17
      octavia/api/v2/controllers/pool.py
  21. 15
      octavia/api/v2/controllers/provider.py
  22. 15
      octavia/api/v2/controllers/quotas.py
  23. 3
      octavia/common/config.py
  24. 3
      octavia/common/keystone.py
  25. 37
      octavia/db/healthcheck.py
  26. 261
      octavia/tests/functional/api/test_healthcheck.py
  27. 6
      releasenotes/notes/add-healthcheck-middleware-6c09150bddd3113f.yaml
  28. 6
      requirements.txt
  29. 2
      setup.cfg

599
doc/source/admin/healthcheck.rst

@ -0,0 +1,599 @@
..
Copyright 2020 Red Hat, Inc. All rights reserved.
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.
=============================
Octavia API Health Monitoring
=============================
The Octavia API provides a health monitoring endpoint that can be used by
external load balancers to manage the Octavia API pool. When properly
configured, the health monitoring endpoint will reflect the full operational
status of the Octavia API.
The Octavia API health monitoring endpoint extends the `OpenStack Oslo
middleware healthcheck <https://docs.openstack.org/oslo.middleware/latest/reference/healthcheck_plugins.html>`_ library to test the Octavia Pecan API framework and associated services.
Oslo Healthcheck Queries
========================
Oslo middleware healthcheck supports HTTP **"GET"** and **"HEAD"** methods.
The response from Oslo middleware healthcheck can be customized by specifying
the acceptable response type for the request.
Oslo middleware healthcheck currently supports the following types:
* text/plain
* text/html
* application/json
If the requested type is not one of the above, it defaults to text/plain.
.. note::
The content of the response "reasons" will vary based on the backend plugins
enabled in Oslo middleware healthcheck. It is a best practice to only rely
on the HTTP status code for Octavia API health monitoring.
Example Responses
-----------------
Example passing output for text/plain with *detailed* False:
.. code-block:: bash
$ curl -i http://198.51.100.10/load-balancer/healthcheck
HTTP/1.1 200 OK
Date: Mon, 16 Mar 2020 18:10:27 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Type: text/plain; charset=UTF-8
Content-Length: 2
x-openstack-request-id: req-9c6f4303-63a7-4f30-8afc-39340658702f
Connection: close
Vary: Accept-Encoding
OK
Example failing output for text/plain with *detailed* False:
.. code-block:: bash
$ curl -i http://198.51.100.10/load-balancer/healthcheck
HTTP/1.1 503 Service Unavailable
Date: Mon, 16 Mar 2020 18:42:12 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Type: text/plain; charset=UTF-8
Content-Length: 36
x-openstack-request-id: req-84024269-2dfb-41ad-bfda-b3e1da138bba
Connection: close
Example passing output for text/html with *detailed* False:
.. code-block:: bash
$ curl -i -H "Accept: text/html" http://198.51.100.10/load-balancer/healthcheck
HTTP/1.1 200 OK
Date: Mon, 16 Mar 2020 18:25:11 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Type: text/html; charset=UTF-8
Content-Length: 239
x-openstack-request-id: req-b212d619-146f-4b50-91a3-5da16051badc
Connection: close
Vary: Accept-Encoding
<HTML>
<HEAD><TITLE>Healthcheck Status</TITLE></HEAD>
<BODY>
<H2>Result of 1 checks:</H2>
<TABLE bgcolor="#ffffff" border="1">
<TBODY>
<TR>
<TH>
Reason
</TH>
</TR>
<TR>
<TD>OK</TD>
</TR>
</TBODY>
</TABLE>
<HR></HR>
</BODY>
</HTML>
Example failing output for text/html with *detailed* False:
.. code-block:: bash
$ curl -i -H "Accept: text/html" http://198.51.100.10/load-balancer/healthcheck
HTTP/1.1 503 Service Unavailable
Date: Mon, 16 Mar 2020 18:42:22 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Type: text/html; charset=UTF-8
Content-Length: 273
x-openstack-request-id: req-c91dd214-85ca-4d33-9fa3-2db81566d9e5
Connection: close
<HTML>
<HEAD><TITLE>Healthcheck Status</TITLE></HEAD>
<BODY>
<H2>Result of 1 checks:</H2>
<TABLE bgcolor="#ffffff" border="1">
<TBODY>
<TR>
<TH>
Reason
</TH>
</TR>
<TR>
<TD>The Octavia database is unavailable.</TD>
</TR>
</TBODY>
</TABLE>
<HR></HR>
</BODY>
</HTML>
Example passing output for application/json with *detailed* False:
.. code-block:: bash
$ curl -i -H "Accept: application/json" http://192.51.100.10/load-balancer/healthcheck
HTTP/1.1 200 OK
Date: Mon, 16 Mar 2020 18:34:42 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Type: application/json
Content-Length: 62
x-openstack-request-id: req-417dc85c-e64e-496e-a461-494a3e6a5479
Connection: close
{
"detailed": false,
"reasons": [
"OK"
]
}
Example failing output for application/json with *detailed* False:
.. code-block:: bash
$ curl -i -H "Accept: application/json" http://192.51.100.10/load-balancer/healthcheck
HTTP/1.1 503 Service Unavailable
Date: Mon, 16 Mar 2020 18:46:28 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Type: application/json
Content-Length: 96
x-openstack-request-id: req-de50b057-6105-4fca-a758-c872ef28bbfa
Connection: close
{
"detailed": false,
"reasons": [
"The Octavia database is unavailable."
]
}
Example Detailed Responses
--------------------------
Example passing output for text/plain with *detailed* True:
.. code-block:: bash
$ curl -i http://198.51.100.10/load-balancer/healthcheck
HTTP/1.1 200 OK
Date: Mon, 16 Mar 2020 18:10:27 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Type: text/plain; charset=UTF-8
Content-Length: 2
x-openstack-request-id: req-9c6f4303-63a7-4f30-8afc-39340658702f
Connection: close
Vary: Accept-Encoding
OK
Example failing output for text/plain with *detailed* True:
.. code-block:: bash
$ curl -i http://198.51.100.10/load-balancer/healthcheck
HTTP/1.1 503 Service Unavailable
Date: Mon, 16 Mar 2020 23:41:23 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Type: text/plain; charset=UTF-8
Content-Length: 36
x-openstack-request-id: req-2cd046cb-3a6c-45e3-921d-5f4a9e65c63e
Connection: close
Example passing output for text/html with *detailed* True:
.. code-block:: bash
$ curl -i -H "Accept: text/html" http://198.51.100.10/load-balancer/healthcheck
HTTP/1.1 200 OK
Date: Mon, 16 Mar 2020 22:11:54 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Type: text/html; charset=UTF-8
Content-Length: 9927
x-openstack-request-id: req-ae7404c9-b183-46dc-bb1b-e5f4e4984a57
Connection: close
Vary: Accept-Encoding
<HTML>
<HEAD><TITLE>Healthcheck Status</TITLE></HEAD>
<BODY>
<H1>Server status</H1>
<B>Server hostname:</B><PRE>devstack2</PRE>
<B>Current time:</B><PRE>2020-03-16 22:11:54.320529</PRE>
<B>Python version:</B><PRE>3.6.9 (default, Nov 7 2019, 10:44:02)
[GCC 8.3.0]</PRE>
<B>Platform:</B><PRE>Linux-4.15.0-88-generic-x86_64-with-Ubuntu-18.04-bionic</PRE>
<HR></HR>
<H2>Garbage collector:</H2>
<B>Counts:</B><PRE>(28, 10, 4)</PRE>
<B>Thresholds:</B><PRE>(700, 10, 10)</PRE>
<HR></HR>
<H2>Result of 1 checks:</H2>
<TABLE bgcolor="#ffffff" border="1">
<TBODY>
<TR>
<TH>
Kind
</TH>
<TH>
Reason
</TH>
<TH>
Details
</TH>
</TR>
<TR>
<TD>OctaviaDBCheckResult</TD>
<TD>OK</TD>
<TD></TD>
</TR>
</TBODY>
</TABLE>
<HR></HR>
<H2>1 greenthread(s) active:</H2>
<TABLE bgcolor="#ffffff" border="1">
<TBODY>
<TR>
<TD><PRE> <...> </PRE></TD>
</TR>
</TBODY>
</TABLE>
<HR></HR>
<H2>1 thread(s) active:</H2>
<TABLE bgcolor="#ffffff" border="1">
<TBODY>
<TR>
<TD><PRE> <...> </PRE></TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
Example failing output for text/html with *detailed* True:
.. code-block:: bash
$ curl -i -H "Accept: text/html" http://198.51.100.10/load-balancer/healthcheck
HTTP/1.1 503 Service Unavailable
Date: Mon, 16 Mar 2020 23:43:52 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Type: text/html; charset=UTF-8
Content-Length: 10211
x-openstack-request-id: req-39b65058-6dc3-4069-a2d5-8a9714dba61d
Connection: close
<HTML>
<HEAD><TITLE>Healthcheck Status</TITLE></HEAD>
<BODY>
<H1>Server status</H1>
<B>Server hostname:</B><PRE>devstack2</PRE>
<B>Current time:</B><PRE>2020-03-16 23:43:52.411127</PRE>
<B>Python version:</B><PRE>3.6.9 (default, Nov 7 2019, 10:44:02)
[GCC 8.3.0]</PRE>
<B>Platform:</B><PRE>Linux-4.15.0-88-generic-x86_64-with-Ubuntu-18.04-bionic</PRE>
<HR></HR>
<H2>Garbage collector:</H2>
<B>Counts:</B><PRE>(578, 10, 4)</PRE>
<B>Thresholds:</B><PRE>(700, 10, 10)</PRE>
<HR></HR>
<H2>Result of 1 checks:</H2>
<TABLE bgcolor="#ffffff" border="1">
<TBODY>
<TR>
<TH>
Kind
</TH>
<TH>
Reason
</TH>
<TH>
Details
</TH>
</TR>
<TR>
<TD>OctaviaDBCheckResult</TD>
<TD>The Octavia database is unavailable.</TD>
<TD>Database health check failed due to: (pymysql.err.OperationalError) (2003, &#34;Can&#39;t connect to MySQL server on &#39;127.0.0.1&#39; ([Errno 111] Connection refused)&#34;)
[SQL: SELECT 1]
(Background on this error at: http://sqlalche.me/e/e3q8).</TD>
</TR>
</TBODY>
</TABLE>
<HR></HR>
<H2>1 greenthread(s) active:</H2>
<TABLE bgcolor="#ffffff" border="1">
<TBODY>
<TR>
<TD><PRE> <...> </PRE></TD>
</TR>
</TBODY>
</TABLE>
<HR></HR>
<H2>1 thread(s) active:</H2>
<TABLE bgcolor="#ffffff" border="1">
<TBODY>
<TR>
<TD><PRE> <...> </PRE></TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
Example passing output for application/json with *detailed* True:
.. code-block:: bash
$ curl -i -H "Accept: application/json" http://192.51.100.10/load-balancer/healthcheck
HTTP/1.1 200 OK
Date: Mon, 16 Mar 2020 22:05:26 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Type: application/json
Content-Length: 9298
x-openstack-request-id: req-d3913655-6e3f-4086-a252-8bb297ea5fd6
Connection: close
{
"detailed": true,
"gc": {
"counts": [
27,
10,
4
],
"threshold": [
700,
10,
10
]
},
"greenthreads": [
<...>
],
"now": "2020-03-16 22:05:26.431429",
"platform": "Linux-4.15.0-88-generic-x86_64-with-Ubuntu-18.04-bionic",
"python_version": "3.6.9 (default, Nov 7 2019, 10:44:02) \n[GCC 8.3.0]",
"reasons": [
{
"class": "OctaviaDBCheckResult",
"details": "",
"reason": "OK"
}
],
"threads": [
<...>
]
}
Example failing output for application/json with *detailed* True:
.. code-block:: bash
$ curl -i -H "Accept: application/json" http://192.51.100.10/load-balancer/healthcheck
HTTP/1.1 503 Service Unavailable
Date: Mon, 16 Mar 2020 23:56:43 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Type: application/json
Content-Length: 9510
x-openstack-request-id: req-3d62ea04-9bdb-4e19-b218-1a81ff7d7337
Connection: close
{
"detailed": true,
"gc": {
"counts": [
178,
0,
5
],
"threshold": [
700,
10,
10
]
},
"greenthreads": [
<...>
],
"now": "2020-03-16 23:58:23.361209",
"platform": "Linux-4.15.0-88-generic-x86_64-with-Ubuntu-18.04-bionic",
"python_version": "3.6.9 (default, Nov 7 2019, 10:44:02) \n[GCC 8.3.0]",
"reasons": [
{
"class": "OctaviaDBCheckResult",
"details": "(pymysql.err.OperationalError) (2003, \"Can't connect to MySQL server on '127.0.0.1' ([Errno 111] Connection refused)\")\n(Background on this error at: http://sqlalche.me/e/e3q8)",
"reason": "The Octavia database is unavailable."
}
],
"threads": [
<...>
]
}
Oslo Healthcheck Plugins
========================
The Octavia API health monitoring endpoint, implemented with Oslo middleware
healthcheck, is extensible using optional backend plugins. There are currently
plugins provided by the Oslo middleware library and plugins provided by
Octavia.
**Oslo middleware provided plugins**
* `disable_by_file <https://docs.openstack.org/oslo.middleware/latest/reference/healthcheck_plugins.html#disable-by-file>`_
* `disable_by_files_ports <https://docs.openstack.org/oslo.middleware/latest/reference/healthcheck_plugins.html#disable-by-files-ports>`_
**Octavia provided plugins**
* `octavia_db_check`_
.. warning::
Some plugins may have long timeouts. It is a best practice to configure your
healthcheck query to have connection, read, and/or data timeouts. The
appropriate values will be unique to each deployment depending on the cloud
performance, number of plugins, etc.
Enabling Octavia API Health Monitoring
======================================
To enable the Octavia API health monitoring endpoint, the proper configuration
file settings need to be updated and the Octavia API processes need to be
restarted.
Start by enabling the endpoint:
.. code-block:: ini
[api_settings]
healthcheck_enabled = True
When the healthcheck_enabled setting is *False*, queries of the /healthcheck
will receive an HTTP 404 Not Found response.
You will then need to select the desired monitoring backend plugins:
.. code-block:: ini
[healthcheck]
backends = octavia_db_check
.. note::
When no plugins are configured, the behavior of Oslo middleware healthcheck
changes. Not only does it not run any tests, it will return 204 results
instead of 200.
Optionally you can enable the "detailed" mode in Oslo middleware healthcheck.
This will cause Oslo middleware healthcheck to return additional information
about the API instance. It will also provide exception details if one was
raised during the health check. This setting is False and disabled by default
in the Octavia API.
.. code-block:: ini
[healthcheck]
detailed = True
.. warning::
Enabling the 'detailed' setting will expose sensitive details about
the API process. Do not enabled this unless you are sure it will
not pose a **security risk** to your API instances.
We highly recommend you do not enable this.
Using Octavia API Health Monitoring
===================================
The Octavia API health monitoring endpoint can be accessed via the
/healthmonitor path on the `Octavia API endpoint <https://docs.openstack.org/api-ref/load-balancer/v2/index.html#service-endpoints>`_.
For example, if your Octavia (load-balancer) endpoint in keystone is:
.. code-block:: bash
https://10.21.21.78/load-balancer
You would access the Octavia API health monitoring endpoint via:
.. code-block:: bash
https://10.21.21.78/load-balancer/healthcheck
A keystone token is not required to access this endpoint.
Octavia Plugins
===============
octavia_db_check
----------------
The octavia_db_check plugin validates the API instance has a working connection
to the Octavia database. It executes a SQL no-op query, 'SELECT 1;', against
the database.
.. note::
Many OpenStack services and libraries, such as oslo.db and sqlalchemy, also
use the no-op query, 'SELECT 1;' for health checks.
The possible octavia_db_check results are:
+---------+--------+-------------+--------------------------------------+
| Request | Result | Status Code | "reason" Message |
+=========+========+=============+======================================+
| GET | Pass | 200 | OK |
+---------+--------+-------------+--------------------------------------+
| HEAD | Pass | 204 | |
+---------+--------+-------------+--------------------------------------+
| GET | Fail | 503 | The Octavia database is unavailable. |
+---------+--------+-------------+--------------------------------------+
| HEAD | Fail | 503 | |
+---------+--------+-------------+--------------------------------------+
When running Oslo middleware healthcheck in "detailed" mode, the "details"
field will have additional information about the error encountered, including
the exception details if they were available.

1
doc/source/admin/index.rst

@ -33,6 +33,7 @@ Optional Installation and Configuration Guides
providers/index.rst
log-offloading.rst
api-audit.rst
healthcheck.rst
flavors.rst
apache-httpd.rst

21
etc/octavia.conf

@ -53,6 +53,9 @@
# The minimum health monitor delay interval for UDP-CONNECT Health Monitor type
# udp_connect_min_interval_health_monitor = 3
# Boolean to enable/disable oslo middleware /healthcheck in the Octavia API
# healthcheck_enabled = False
[database]
# This line MUST be changed to actually run the plugin.
# Example:
@ -572,3 +575,21 @@
# List of enabled provider agents.
# enabled_provider_agents =
[healthcheck]
# WARNING: Enabling the 'detailed' setting will expose sensitive details about
# the API process. Do not enabled this unless you are sure it will
# not pose a security risk to your API instances.
# We highly recommend you do not enable this.
# detailed = False
# This is a list of oslo middleware healthcheck backend plugins to enable for
# the oslo middleware health check.
#
# Plugins provided by oslo middleware:
# disable_by_file
# disable_by_files_ports
# Plugins provided by Octavia:
# octavia_db_check
#
# backends =

6
lower-constraints.txt

@ -86,7 +86,7 @@ oslo.db==4.27.0
oslo.i18n==3.15.3
oslo.log==3.36.0
oslo.messaging==6.3.0
oslo.middleware==3.31.0
oslo.middleware==4.0.1
oslo.policy==1.30.0
oslo.reports==1.18.0
oslo.serialization==2.18.0
@ -99,7 +99,7 @@ paramiko==2.4.1
Paste==2.0.3
PasteDeploy==1.5.2
pbr==2.0.0
pecan==1.0.0
pecan==1.3.2
pep8==1.7.1
pika==0.10.0
pika-pool==0.1.3
@ -169,7 +169,7 @@ vine==1.1.4
voluptuous==0.11.1
waitress==1.1.0
warlock==1.3.0
WebOb==1.7.1
WebOb==1.8.2
WebTest==2.0.29
Werkzeug==0.14.1
wrapt==1.10.11

9
octavia/api/app.py

@ -20,7 +20,8 @@ from oslo_log import log as logging
from oslo_middleware import cors
from oslo_middleware import http_proxy_to_wsgi
from oslo_middleware import request_id
import pecan
from pecan import configuration as pecan_configuration
from pecan import make_app as pecan_make_app
from octavia.api import config as app_config
from octavia.api.drivers import driver_factory
@ -36,7 +37,7 @@ CONF = cfg.CONF
def get_pecan_config():
"""Returns the pecan config."""
filename = app_config.__file__.replace('.pyc', '.py')
return pecan.configuration.conf_from_file(filename)
return pecan_configuration.conf_from_file(filename)
def _init_drivers():
@ -56,9 +57,9 @@ def setup_app(pecan_config=None, debug=False, argv=None):
if not pecan_config:
pecan_config = get_pecan_config()
pecan.configuration.set_config(dict(pecan_config), overwrite=True)
pecan_configuration.set_config(dict(pecan_config), overwrite=True)
return pecan.make_app(
return pecan_make_app(
pecan_config.app.root,
wrap_app=_wrap_app,
debug=debug,

47
octavia/api/healthcheck/healthcheck_plugins.py

@ -0,0 +1,47 @@
# Copyright 2020 Red Hat, Inc. All rights reserved.
#
# 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.
from oslo_middleware.healthcheck import pluginbase
from octavia.db import api as db_apis
from octavia.db import healthcheck
class OctaviaDBHealthcheck(pluginbase.HealthcheckBaseExtension):
UNAVAILABLE_REASON = 'The Octavia database is unavailable.'
def __init__(self, *args, **kwargs):
super(OctaviaDBHealthcheck, self).__init__(*args, **kwargs)
def healthcheck(self, server_port):
try:
result, message = healthcheck.check_database_connection(
db_apis.get_session())
if result:
return OctaviaDBCheckResult(available=True, reason="OK")
else:
return OctaviaDBCheckResult(available=False,
reason=self.UNAVAILABLE_REASON,
details=message)
except Exception as e:
return OctaviaDBCheckResult(available=False,
reason=self.UNAVAILABLE_REASON,
details=str(e))
class OctaviaDBCheckResult(pluginbase.HealthcheckResult):
"""Result sub-class to provide a unique name in detail reports."""
def __init__(self, *args, **kwargs):
super(OctaviaDBCheckResult, self).__init__(*args, **kwargs)

24
octavia/api/root_controller.py

@ -12,25 +12,41 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_config import cfg
from oslo_log import log as logging
from oslo_middleware import healthcheck
from pecan import abort as pecan_abort
from pecan import expose as pecan_expose
from pecan import request as pecan_request
from pecan import rest
from wsme import types as wtypes
from wsmeext import pecan as wsme_pecan
from octavia.api.v2 import controllers as v2_controller
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
class RootController(rest.RestController):
class RootController(object):
"""The controller with which the pecan wsgi app should be created."""
def __init__(self):
super(RootController, self).__init__()
setattr(self, 'v2.0', v2_controller.V2Controller())
setattr(self, 'v2', v2_controller.V2Controller())
if CONF.api_settings.healthcheck_enabled:
self.healthcheck_obj = healthcheck.Healthcheck.app_factory(None)
# Run the oslo middleware healthcheck for /healthcheck
@pecan_expose('json')
@pecan_expose(content_type='plain/text')
@pecan_expose(content_type='text/html')
def healthcheck(self): # pylint: disable=inconsistent-return-statements
if CONF.api_settings.healthcheck_enabled:
if pecan_request.method not in ['GET', 'HEAD']:
pecan_abort(405)
return self.healthcheck_obj.process_request(pecan_request)
pecan_abort(404)
def _add_a_version(self, versions, version, url_version, status,
timestamp, base_url):
@ -45,7 +61,7 @@ class RootController(rest.RestController):
})
@wsme_pecan.wsexpose(wtypes.text)
def get(self):
def index(self):
host_url = pecan_request.path_url
if not host_url.endswith('/'):

15
octavia/api/v2/controllers/amphora.py

@ -17,7 +17,8 @@ from oslo_config import cfg
from oslo_log import log as logging
import oslo_messaging as messaging
from oslo_utils import excutils
import pecan
from pecan import expose as pecan_expose
from pecan import request as pecan_request
from wsme import types as wtypes
from wsmeext import pecan as wsme_pecan
@ -41,7 +42,7 @@ class AmphoraController(base.BaseController):
[wtypes.text], ignore_extra_args=True)
def get_one(self, id, fields=None):
"""Gets a single amphora's details."""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
db_amp = self._get_db_amp(context.session, id, show_deleted=False)
self._auth_validate_action(context, context.project_id,
@ -57,7 +58,7 @@ class AmphoraController(base.BaseController):
ignore_extra_args=True)
def get_all(self, fields=None):
"""Gets all health monitors."""
pcontext = pecan.request.context
pcontext = pecan_request.context
context = pcontext.get('octavia_context')
self._auth_validate_action(context, context.project_id,
@ -73,7 +74,7 @@ class AmphoraController(base.BaseController):
return amp_types.AmphoraeRootResponse(
amphorae=result, amphorae_links=links)
@pecan.expose()
@pecan_expose()
def _lookup(self, amphora_id, *remainder):
"""Overridden pecan _lookup method for custom routing.
@ -107,7 +108,7 @@ class FailoverController(base.BaseController):
@wsme_pecan.wsexpose(None, wtypes.text, status_code=202)
def put(self):
"""Fails over an amphora"""
pcontext = pecan.request.context
pcontext = pecan_request.context
context = pcontext.get('octavia_context')
db_amp = self._get_db_amp(context.session, self.amp_id,
show_deleted=False)
@ -153,7 +154,7 @@ class AmphoraUpdateController(base.BaseController):
@wsme_pecan.wsexpose(None, wtypes.text, status_code=202)
def put(self):
"""Update amphora agent configuration"""
pcontext = pecan.request.context
pcontext = pecan_request.context
context = pcontext.get('octavia_context')
db_amp = self._get_db_amp(context.session, self.amp_id,
show_deleted=False)
@ -188,7 +189,7 @@ class AmphoraStatsController(base.BaseController):
@wsme_pecan.wsexpose(amp_types.StatisticsRootResponse, wtypes.text,
status_code=200)
def get(self):
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_GET_STATS)

12
octavia/api/v2/controllers/availability_zone_profiles.py

@ -17,7 +17,7 @@ from oslo_log import log as logging
from oslo_serialization import jsonutils
from oslo_utils import excutils
from oslo_utils import uuidutils
import pecan
from pecan import request as pecan_request
from sqlalchemy.orm import exc as sa_exception
from wsme import types as wtypes
from wsmeext import pecan as wsme_pecan
@ -43,7 +43,7 @@ class AvailabilityZoneProfileController(base.BaseController):
wtypes.text, [wtypes.text], ignore_extra_args=True)
def get_one(self, id, fields=None):
"""Gets an Availability Zone Profile's detail."""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_GET_ONE)
if id == constants.NIL_UUID:
@ -63,7 +63,7 @@ class AvailabilityZoneProfileController(base.BaseController):
[wtypes.text], ignore_extra_args=True)
def get_all(self, fields=None):
"""Lists all Availability Zone Profiles."""
pcontext = pecan.request.context
pcontext = pecan_request.context
context = pcontext.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_GET_ALL)
@ -87,7 +87,7 @@ class AvailabilityZoneProfileController(base.BaseController):
"""Creates an Availability Zone Profile."""
availability_zone_profile = (
availability_zone_profile_.availability_zone_profile)
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_POST)
# Do a basic JSON validation on the metadata
@ -155,7 +155,7 @@ class AvailabilityZoneProfileController(base.BaseController):
"""Updates an Availability Zone Profile."""
availability_zone_profile = (
availability_zone_profile_.availability_zone_profile)
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_PUT)
@ -216,7 +216,7 @@ class AvailabilityZoneProfileController(base.BaseController):
@wsme_pecan.wsexpose(None, wtypes.text, status_code=204)
def delete(self, availability_zone_profile_id):
"""Deletes an Availability Zone Profile"""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_DELETE)

12
octavia/api/v2/controllers/availability_zones.py

@ -16,7 +16,7 @@ from oslo_db import api as oslo_db_api
from oslo_db import exception as odb_exceptions
from oslo_log import log as logging
from oslo_utils import excutils
import pecan
from pecan import request as pecan_request
from sqlalchemy.orm import exc as sa_exception
from wsme import types as wtypes
from wsmeext import pecan as wsme_pecan
@ -40,7 +40,7 @@ class AvailabilityZonesController(base.BaseController):
wtypes.text, [wtypes.text], ignore_extra_args=True)
def get_one(self, name, fields=None):
"""Gets an Availability Zone's detail."""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_GET_ONE)
if name == constants.NIL_UUID:
@ -60,7 +60,7 @@ class AvailabilityZonesController(base.BaseController):
[wtypes.text], ignore_extra_args=True)
def get_all(self, fields=None):
"""Lists all Availability Zones."""
pcontext = pecan.request.context
pcontext = pecan_request.context
context = pcontext.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_GET_ALL)
@ -82,7 +82,7 @@ class AvailabilityZonesController(base.BaseController):
def post(self, availability_zone_):
"""Creates an Availability Zone."""
availability_zone = availability_zone_.availability_zone
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_POST)
@ -111,7 +111,7 @@ class AvailabilityZonesController(base.BaseController):
body=availability_zone_types.AvailabilityZoneRootPUT)
def put(self, name, availability_zone_):
availability_zone = availability_zone_.availability_zone
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_PUT)
if name == constants.NIL_UUID:
@ -144,7 +144,7 @@ class AvailabilityZonesController(base.BaseController):
@wsme_pecan.wsexpose(None, wtypes.text, status_code=204)
def delete(self, availability_zone_name):
"""Deletes an Availability Zone"""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_DELETE)

9
octavia/api/v2/controllers/base.py

@ -16,7 +16,8 @@ from cryptography.hazmat.backends import default_backend
from cryptography import x509
from oslo_config import cfg
from oslo_log import log as logging
import pecan
from pecan import request as pecan_request
from pecan import rest as pecan_rest
from stevedore import driver as stevedore_driver
from wsme import types as wtypes
@ -31,7 +32,7 @@ CONF = cfg.CONF
LOG = logging.getLogger(__name__)
class BaseController(pecan.rest.RestController):
class BaseController(pecan_rest.RestController):
RBAC_TYPE = None
def __init__(self):
@ -257,7 +258,7 @@ class BaseController(pecan.rest.RestController):
return attrs
def _validate_tls_refs(self, tls_refs):
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
bad_refs = []
for ref in tls_refs:
try:
@ -272,7 +273,7 @@ class BaseController(pecan.rest.RestController):
raise exceptions.CertificateRetrievalException(ref=bad_refs)
def _validate_client_ca_and_crl_refs(self, client_ca_ref, crl_ref):
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
bad_refs = []
try:
self.cert_manager.set_acls(context, client_ca_ref)

12
octavia/api/v2/controllers/flavor_profiles.py

@ -18,7 +18,7 @@ from oslo_log import log as logging
from oslo_serialization import jsonutils
from oslo_utils import excutils
from oslo_utils import uuidutils
import pecan
from pecan import request as pecan_request
from sqlalchemy.orm import exc as sa_exception
from wsme import types as wtypes
from wsmeext import pecan as wsme_pecan
@ -44,7 +44,7 @@ class FlavorProfileController(base.BaseController):
[wtypes.text], ignore_extra_args=True)
def get_one(self, id, fields=None):
"""Gets a flavor profile's detail."""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_GET_ONE)
if id == constants.NIL_UUID:
@ -61,7 +61,7 @@ class FlavorProfileController(base.BaseController):
[wtypes.text], ignore_extra_args=True)
def get_all(self, fields=None):
"""Lists all flavor profiles."""
pcontext = pecan.request.context
pcontext = pecan_request.context
context = pcontext.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_GET_ALL)
@ -81,7 +81,7 @@ class FlavorProfileController(base.BaseController):
def post(self, flavor_profile_):
"""Creates a flavor Profile."""
flavorprofile = flavor_profile_.flavorprofile
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_POST)
# Do a basic JSON validation on the metadata
@ -138,7 +138,7 @@ class FlavorProfileController(base.BaseController):
def put(self, id, flavor_profile_):
"""Updates a flavor Profile."""
flavorprofile = flavor_profile_.flavorprofile
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_PUT)
@ -190,7 +190,7 @@ class FlavorProfileController(base.BaseController):
@wsme_pecan.wsexpose(None, wtypes.text, status_code=204)
def delete(self, flavor_profile_id):
"""Deletes a Flavor Profile"""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_DELETE)

12
octavia/api/v2/controllers/flavors.py

@ -18,7 +18,7 @@ from oslo_db import exception as odb_exceptions
from oslo_log import log as logging
from oslo_utils import excutils
from oslo_utils import uuidutils
import pecan
from pecan import request as pecan_request
from sqlalchemy.orm import exc as sa_exception
from wsme import types as wtypes
from wsmeext import pecan as wsme_pecan
@ -42,7 +42,7 @@ class FlavorsController(base.BaseController):
[wtypes.text], ignore_extra_args=True)
def get_one(self, id, fields=None):
"""Gets a flavor's detail."""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_GET_ONE)
if id == constants.NIL_UUID:
@ -58,7 +58,7 @@ class FlavorsController(base.BaseController):
[wtypes.text], ignore_extra_args=True)
def get_all(self, fields=None):
"""Lists all flavors."""
pcontext = pecan.request.context
pcontext = pecan_request.context
context = pcontext.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_GET_ALL)
@ -77,7 +77,7 @@ class FlavorsController(base.BaseController):
def post(self, flavor_):
"""Creates a flavor."""
flavor = flavor_.flavor
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_POST)
@ -106,7 +106,7 @@ class FlavorsController(base.BaseController):
body=flavor_types.FlavorRootPUT)
def put(self, id, flavor_):
flavor = flavor_.flavor
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_PUT)
if id == constants.NIL_UUID:
@ -134,7 +134,7 @@ class FlavorsController(base.BaseController):
@wsme_pecan.wsexpose(None, wtypes.text, status_code=204)
def delete(self, flavor_id):
"""Deletes a Flavor"""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
self._auth_validate_action(context, context.project_id,
constants.RBAC_DELETE)

12
octavia/api/v2/controllers/health_monitor.py

@ -17,7 +17,7 @@ from oslo_config import cfg
from oslo_db import exception as odb_exceptions
from oslo_log import log as logging
from oslo_utils import excutils
import pecan
from pecan import request as pecan_request
from wsme import types as wtypes
from wsmeext import pecan as wsme_pecan
@ -48,7 +48,7 @@ class HealthMonitorController(base.BaseController):
[wtypes.text], ignore_extra_args=True)
def get_one(self, id, fields=None):
"""Gets a single healthmonitor's details."""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
db_hm = self._get_db_hm(context.session, id, show_deleted=False)
self._auth_validate_action(context, db_hm.project_id,
@ -64,7 +64,7 @@ class HealthMonitorController(base.BaseController):
[wtypes.text], ignore_extra_args=True)
def get_all(self, project_id=None, fields=None):
"""Gets all health monitors."""
pcontext = pecan.request.context
pcontext = pecan_request.context
context = pcontext.get('octavia_context')
query_filter = self._auth_get_all(context, project_id)
@ -196,7 +196,7 @@ class HealthMonitorController(base.BaseController):
body=hm_types.HealthMonitorRootPOST, status_code=201)
def post(self, health_monitor_):
"""Creates a health monitor on a pool."""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
health_monitor = health_monitor_.healthmonitor
if (not CONF.api_settings.allow_ping_health_monitors and
@ -334,7 +334,7 @@ class HealthMonitorController(base.BaseController):
body=hm_types.HealthMonitorRootPUT, status_code=200)
def put(self, id, health_monitor_):
"""Updates a health monitor."""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
health_monitor = health_monitor_.healthmonitor
db_hm = self._get_db_hm(context.session, id, show_deleted=False)
@ -393,7 +393,7 @@ class HealthMonitorController(base.BaseController):
@wsme_pecan.wsexpose(None, wtypes.text, status_code=204)
def delete(self, id):
"""Deletes a health monitor."""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
db_hm = self._get_db_hm(context.session, id, show_deleted=False)
pool = self._get_db_pool(context.session, db_hm.pool_id)

17
octavia/api/v2/controllers/l7policy.py

@ -16,7 +16,8 @@ from oslo_config import cfg
from oslo_db import exception as odb_exceptions
from oslo_log import log as logging
from oslo_utils import excutils
import pecan
from pecan import expose as pecan_expose
from pecan import request as pecan_request
from wsme import types as wtypes
from wsmeext import pecan as wsme_pecan
@ -48,7 +49,7 @@ class L7PolicyController(base.BaseController):
[wtypes.text], ignore_extra_args=True)
def get(self, id, fields=None):
"""Gets a single l7policy's details."""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
db_l7policy = self._get_db_l7policy(context.session, id,
show_deleted=False)
@ -65,7 +66,7 @@ class L7PolicyController(base.BaseController):
[wtypes.text], ignore_extra_args=True)
def get_all(self, project_id=None, fields=None):
"""Lists all l7policies of a listener."""
pcontext = pecan.request.context
pcontext = pecan_request.context
context = pcontext.get('octavia_context')
query_filter = self._auth_get_all(context, project_id)
@ -115,7 +116,7 @@ class L7PolicyController(base.BaseController):
def post(self, l7policy_):
"""Creates a l7policy on a listener."""
l7policy = l7policy_.l7policy
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
# Verify the parent listener exists
listener_id = l7policy.listener_id
listener = self._get_db_listener(
@ -206,7 +207,7 @@ class L7PolicyController(base.BaseController):
if val in l7policy_dict:
l7policy_dict[attr] = l7policy_dict.pop(val)
sanitized_l7policy = l7policy_types.L7PolicyPUT(**l7policy_dict)
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
db_l7policy = self._get_db_l7policy(context.session, id,
show_deleted=False)
@ -268,7 +269,7 @@ class L7PolicyController(base.BaseController):
@wsme_pecan.wsexpose(None, wtypes.text, status_code=204)
def delete(self, id):
"""Deletes a l7policy."""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
db_l7policy = self._get_db_l7policy(context.session, id,
show_deleted=False)
load_balancer_id, listener_id = self._get_listener_and_loadbalancer_id(
@ -300,14 +301,14 @@ class L7PolicyController(base.BaseController):
driver_utils.call_provider(driver.name, driver.l7policy_delete,
provider_l7policy)
@pecan.expose()
@pecan_expose()
def _lookup(self, l7policy_id, *remainder):
"""Overridden pecan _lookup method for custom routing.
Verifies that the l7policy passed in the url exists, and if so decides
which controller, if any, should control be passed.
"""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
if l7policy_id and remainder and remainder[0] == 'rules':
remainder = remainder[1:]
db_l7policy = self.repositories.l7policy.get(

12
octavia/api/v2/controllers/l7rule.py

@ -15,7 +15,7 @@
from oslo_db import exception as odb_exceptions
from oslo_log import log as logging
from oslo_utils import excutils
import pecan
from pecan import request as pecan_request
from wsme import types as wtypes
from wsmeext import pecan as wsme_pecan
@ -46,7 +46,7 @@ class L7RuleController(base.BaseController):
[wtypes.text], ignore_extra_args=True)
def get(self, id, fields=None):
"""Gets a single l7rule's details."""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
db_l7rule = self._get_db_l7rule(context.session, id,
show_deleted=False)
@ -63,7 +63,7 @@ class L7RuleController(base.BaseController):
ignore_extra_args=True)
def get_all(self, fields=None):
"""Lists all l7rules of a l7policy."""
pcontext = pecan.request.context
pcontext = pecan_request.context
context = pcontext.get('octavia_context')
l7policy = self._get_db_l7policy(context.session, self.l7policy_id,
@ -127,7 +127,7 @@ class L7RuleController(base.BaseController):
validate.l7rule_data(l7rule)
except Exception as e:
raise exceptions.L7RuleValidation(error=e)
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
db_l7policy = self._get_db_l7policy(context.session, self.l7policy_id,
show_deleted=False)
@ -189,7 +189,7 @@ class L7RuleController(base.BaseController):
def put(self, id, l7rule_):
"""Updates a l7rule."""
l7rule = l7rule_.rule
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
db_l7rule = self._get_db_l7rule(context.session, id,
show_deleted=False)
@ -256,7 +256,7 @@ class L7RuleController(base.BaseController):
@wsme_pecan.wsexpose(None, wtypes.text, status_code=204)
def delete(self, id):
"""Deletes a l7rule."""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
db_l7rule = self._get_db_l7rule(context.session, id,
show_deleted=False)

19
octavia/api/v2/controllers/listener.py

@ -17,7 +17,8 @@ from oslo_config import cfg
from oslo_db import exception as odb_exceptions
from oslo_log import log as logging
from oslo_utils import excutils
import pecan
from pecan import expose as pecan_expose
from pecan import request as pecan_request
from wsme import types as wtypes
from wsmeext import pecan as wsme_pecan
@ -51,7 +52,7 @@ class ListenersController(base.BaseController):
[wtypes.text], ignore_extra_args=True)
def get_one(self, id, fields=None):
"""Gets a single listener's details."""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
db_listener = self._get_db_listener(context.session, id,
show_deleted=False)
@ -72,7 +73,7 @@ class ListenersController(base.BaseController):
[wtypes.text], ignore_extra_args=True)
def get_all(self, project_id=None, fields=None):
"""Lists all listeners."""
pcontext = pecan.request.context
pcontext = pecan_request.context
context = pcontext.get('octavia_context')
query_filter = self._auth_get_all(context, project_id)
@ -237,7 +238,7 @@ class ListenersController(base.BaseController):
# Validate that the L4 protocol (UDP or TCP) is not already used for
# the specified protocol_port in this load balancer
pcontext = pecan.request.context
pcontext = pecan_request.context
query_filter = {
'project_id': listener_dict['project_id'],
'load_balancer_id': listener_dict['load_balancer_id'],
@ -310,7 +311,7 @@ class ListenersController(base.BaseController):
def post(self, listener_):
"""Creates a listener on a load balancer."""
listener = listener_.listener
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
load_balancer_id = listener.loadbalancer_id
listener.project_id, provider = self._get_lb_project_id_provider(
@ -507,7 +508,7 @@ class ListenersController(base.BaseController):
def put(self, id, listener_):
"""Updates a listener on a load balancer."""
listener = listener_.listener
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
db_listener = self._get_db_listener(context.session, id,
show_deleted=False)
load_balancer_id = db_listener.load_balancer_id
@ -567,7 +568,7 @@ class ListenersController(base.BaseController):
@wsme_pecan.wsexpose(None, wtypes.text, status_code=204)
def delete(self, id):
"""Deletes a listener from a load balancer."""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
db_listener = self._get_db_listener(context.session, id,
show_deleted=False)
load_balancer_id = db_listener.load_balancer_id
@ -594,7 +595,7 @@ class ListenersController(base.BaseController):
driver_utils.call_provider(driver.name, driver.listener_delete,
provider_listener)
@pecan.expose()
@pecan_expose()
def _lookup(self, id, *remainder):
"""Overridden pecan _lookup method for custom routing.
@ -616,7 +617,7 @@ class StatisticsController(base.BaseController, stats.StatsMixin):
@wsme_pecan.wsexpose(listener_types.StatisticsRootResponse, wtypes.text,
status_code=200)
def get(self):
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
db_listener = self._get_db_listener(context.session, self.id,
show_deleted=False)
if not db_listener:

21
octavia/api/v2/controllers/load_balancer.py

@ -18,7 +18,8 @@ from oslo_db import exception as odb_exceptions
from oslo_log import log as logging
from oslo_utils import excutils
from oslo_utils import strutils
import pecan
from pecan import expose as pecan_expose
from pecan import request as pecan_request
from sqlalchemy.orm import exc as sa_exception
from wsme import types as wtypes
from wsmeext import pecan as wsme_pecan
@ -56,7 +57,7 @@ class LoadBalancersController(base.BaseController):
[wtypes.text], ignore_extra_args=True)
def get_one(self, id, fields=None):
"""Gets a single load balancer's details."""
context = pecan.request.context.get('octavia_context')
context = pecan_request.context.get('octavia_context')
load_balancer = self._get_db_lb(context.session, id,
show_deleted=False)
@ -78,7 +79,7 @@ class LoadBalancersController(base.BaseController):
[wtypes.text], ignore_extra_args=True)
def get_all(self, project_id=None, fields=None):
"""Lists all load balancers."""
pcontext = pecan.request.context
pcontext = pecan_request.context