summaryrefslogtreecommitdiff
path: root/oslo_middleware
diff options
context:
space:
mode:
Diffstat (limited to 'oslo_middleware')
-rw-r--r--oslo_middleware/healthcheck/__init__.py22
-rw-r--r--oslo_middleware/healthcheck/disable_by_file.py38
-rw-r--r--oslo_middleware/healthcheck/opts.py46
-rw-r--r--oslo_middleware/healthcheck/pluginbase.py11
-rw-r--r--oslo_middleware/opts.py31
-rw-r--r--oslo_middleware/tests/test_healthcheck.py5
6 files changed, 127 insertions, 26 deletions
diff --git a/oslo_middleware/healthcheck/__init__.py b/oslo_middleware/healthcheck/__init__.py
index ce2b03a..65c2791 100644
--- a/oslo_middleware/healthcheck/__init__.py
+++ b/oslo_middleware/healthcheck/__init__.py
@@ -37,6 +37,7 @@ except ImportError:
greenlet = None
from oslo_middleware import base
+from oslo_middleware.healthcheck import opts
def _find_objects(t):
@@ -374,18 +375,16 @@ Reason
</HTML>
"""
- def __init__(self, application, conf):
- super(Healthcheck, self).__init__(application)
- self._path = conf.get('path', '/healthcheck')
- self._show_details = strutils.bool_from_string(conf.get('detailed'))
- self._backend_names = []
- backends = conf.get('backends')
- if backends:
- self._backend_names = backends.split(',')
+ def __init__(self, *args, **kwargs):
+ super(Healthcheck, self).__init__(*args, **kwargs)
+ self.oslo_conf.register_opts(opts.HEALTHCHECK_OPTS,
+ group='healthcheck')
+ self._path = self._conf_get('path')
+ self._show_details = self._conf_get('detailed')
self._backends = stevedore.NamedExtensionManager(
- self.NAMESPACE, self._backend_names,
+ self.NAMESPACE, self._conf_get('backends'),
name_order=True, invoke_on_load=True,
- invoke_args=(conf,))
+ invoke_args=(self.oslo_conf, self.conf))
self._accept_to_functor = collections.OrderedDict([
# Order here matters...
('text/plain', self._make_text_response),
@@ -398,6 +397,9 @@ Reason
# middleware actually can cause issues).
self._default_accept = 'text/plain'
+ def _conf_get(self, key, group='healthcheck'):
+ return super(Healthcheck, self)._conf_get(key, group=group)
+
@staticmethod
def _get_threadstacks():
threadstacks = []
diff --git a/oslo_middleware/healthcheck/disable_by_file.py b/oslo_middleware/healthcheck/disable_by_file.py
index 7fbb14b..1b3ffa3 100644
--- a/oslo_middleware/healthcheck/disable_by_file.py
+++ b/oslo_middleware/healthcheck/disable_by_file.py
@@ -17,6 +17,7 @@ import logging
import os
from oslo_middleware._i18n import _LW
+from oslo_middleware.healthcheck import opts
from oslo_middleware.healthcheck import pluginbase
LOG = logging.getLogger(__name__)
@@ -40,23 +41,25 @@ class DisableByFilesPortsHealthcheck(pluginbase.HealthcheckBaseExtension):
disable_by_file_paths = 5000:/var/run/keystone/healthcheck_disable, \
35357:/var/run/keystone/admin_healthcheck_disable
"""
- def __init__(self, conf):
- super(DisableByFilesPortsHealthcheck, self).__init__(conf)
+
+ def __init__(self, *args, **kwargs):
+ super(DisableByFilesPortsHealthcheck, self).__init__(*args, **kwargs)
+ self.oslo_conf.register_opts(opts.DISABLE_BY_FILES_OPTS,
+ group='healthcheck')
self.status_files = {}
- self.status_files.update(
- self._iter_paths_ports(self.conf.get('disable_by_file_paths')))
+ paths = self._conf_get('disable_by_file_paths')
+ self.status_files.update(self._iter_paths_ports(paths))
@staticmethod
def _iter_paths_ports(paths):
- if paths:
- for port_path in paths.split(","):
- port_path = port_path.strip()
- if port_path:
- # On windows, drive letters are followed by colons,
- # which makes split() return 3 elements in this case
- port, path = port_path.split(":", 1)
- port = int(port)
- yield (port, path)
+ for port_path in paths:
+ port_path = port_path.strip()
+ if port_path:
+ # On windows, drive letters are followed by colons,
+ # which makes split() return 3 elements in this case
+ port, path = port_path.split(":", 1)
+ port = int(port)
+ yield (port, path)
def healthcheck(self, server_port):
path = self.status_files.get(server_port)
@@ -92,9 +95,14 @@ class DisableByFileHealthcheck(pluginbase.HealthcheckBaseExtension):
disable_by_file_path = /var/run/nova/healthcheck_disable
"""
+ def __init__(self, *args, **kwargs):
+ super(DisableByFileHealthcheck, self).__init__(*args, **kwargs)
+ self.oslo_conf.register_opts(opts.DISABLE_BY_FILE_OPTS,
+ group='healthcheck')
+
def healthcheck(self, server_port):
- path = self.conf.get('disable_by_file_path')
- if path is None:
+ path = self._conf_get('disable_by_file_path')
+ if not path:
LOG.warning(_LW('DisableByFile healthcheck middleware enabled '
'without disable_by_file_path set'))
return pluginbase.HealthcheckResult(
diff --git a/oslo_middleware/healthcheck/opts.py b/oslo_middleware/healthcheck/opts.py
new file mode 100644
index 0000000..d283f4d
--- /dev/null
+++ b/oslo_middleware/healthcheck/opts.py
@@ -0,0 +1,46 @@
+# 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_config import cfg
+
+
+HEALTHCHECK_OPTS = [
+ cfg.StrOpt('path',
+ default='/healthcheck',
+ help='The path to respond to healtcheck requests on.'),
+ cfg.BoolOpt('detailed',
+ default=False,
+ help='Show more detailed information as part of the response'),
+ cfg.ListOpt('backends',
+ default=[],
+ help='Additional backends that can perform health checks and '
+ 'report that information back as part of a request.'),
+]
+
+
+DISABLE_BY_FILE_OPTS = [
+ cfg.StrOpt('disable_by_file_path',
+ default=None,
+ help='Check the presence of a file to determine if an '
+ 'application is running on a port. Used by '
+ 'DisableByFileHealthcheck plugin.'),
+]
+
+
+DISABLE_BY_FILES_OPTS = [
+ cfg.ListOpt('disable_by_file_paths',
+ default=[],
+ help='Check the presence of a file based on a port to '
+ 'determine if an application is running on a port. '
+ 'Expects a "port:path" list of strings. Used by '
+ 'DisableByFilesPortsHealthcheck plugin.'),
+]
diff --git a/oslo_middleware/healthcheck/pluginbase.py b/oslo_middleware/healthcheck/pluginbase.py
index e370967..eb8013d 100644
--- a/oslo_middleware/healthcheck/pluginbase.py
+++ b/oslo_middleware/healthcheck/pluginbase.py
@@ -29,7 +29,9 @@ class HealthcheckResult(object):
@six.add_metaclass(abc.ABCMeta)
class HealthcheckBaseExtension(object):
- def __init__(self, conf):
+
+ def __init__(self, oslo_conf, conf):
+ self.oslo_conf = oslo_conf
self.conf = conf
@abc.abstractmethod
@@ -38,3 +40,10 @@ class HealthcheckBaseExtension(object):
return: HealthcheckResult object
"""
+
+ def _conf_get(self, key, group='healthcheck'):
+ if key in self.conf:
+ # Validate value type
+ self.oslo_conf.set_override(key, self.conf[key], group=group,
+ enforce_type=True)
+ return getattr(getattr(self.oslo_conf, group), key)
diff --git a/oslo_middleware/opts.py b/oslo_middleware/opts.py
index e66e723..1584f9b 100644
--- a/oslo_middleware/opts.py
+++ b/oslo_middleware/opts.py
@@ -19,6 +19,7 @@ __all__ = [
'list_opts_ssl',
'list_opts_cors',
'list_opts_http_proxy_to_wsgi',
+ 'list_opts_healthcheck',
]
@@ -26,6 +27,7 @@ import copy
import itertools
from oslo_middleware import cors
+from oslo_middleware.healthcheck import opts as healthcheck_opts
from oslo_middleware import http_proxy_to_wsgi
from oslo_middleware import sizelimit
from oslo_middleware import ssl
@@ -56,6 +58,7 @@ def list_opts():
list_opts_ssl(),
list_opts_cors(),
list_opts_http_proxy_to_wsgi(),
+ list_opts_healthcheck(),
)
)
@@ -155,3 +158,31 @@ def list_opts_http_proxy_to_wsgi():
return [
('oslo_middleware', copy.deepcopy(http_proxy_to_wsgi.OPTS)),
]
+
+
+def list_opts_healthcheck():
+ """Return a list of oslo.config options for healthcheck.
+
+ The returned list includes all oslo.config options which may be registered
+ at runtime by the library.
+
+ Each element of the list is a tuple. The first element is the name of the
+ group under which the list of elements in the second element will be
+ registered. A group name of None corresponds to the [DEFAULT] group in
+ config files.
+
+ This function is also discoverable via the 'oslo.middleware' entry point
+ under the 'oslo.config.opts' namespace.
+
+ The purpose of this is to allow tools like the Oslo sample config file
+ generator to discover the options exposed to users by this library.
+
+ :returns: a list of (group_name, opts) tuples
+ """
+ # standard opts and the most common plugin to turn up in sample config.
+ # can figure out a better way of exposing plugin opts later if required.
+ return [
+ ('healthcheck', copy.deepcopy(healthcheck_opts.HEALTHCHECK_OPTS +
+ healthcheck_opts.DISABLE_BY_FILE_OPTS +
+ healthcheck_opts.DISABLE_BY_FILES_OPTS))
+ ]
diff --git a/oslo_middleware/tests/test_healthcheck.py b/oslo_middleware/tests/test_healthcheck.py
index df73969..793a895 100644
--- a/oslo_middleware/tests/test_healthcheck.py
+++ b/oslo_middleware/tests/test_healthcheck.py
@@ -17,6 +17,7 @@ import threading
import time
import mock
+from oslo_config import fixture as config
from oslotest import base as test_base
import requests
import webob.dec
@@ -50,6 +51,10 @@ class HealthcheckMainTests(test_base.BaseTestCase):
class HealthcheckTests(test_base.BaseTestCase):
+ def setUp(self):
+ super(HealthcheckTests, self).setUp()
+ self.useFixture(config.Config())
+
@staticmethod
@webob.dec.wsgify
def application(req):