diff --git a/ceilometer/api/app.py b/ceilometer/api/app.py index 896ed7916..9dedac545 100644 --- a/ceilometer/api/app.py +++ b/ceilometer/api/app.py @@ -18,8 +18,10 @@ import logging import os +import socket from wsgiref import simple_server +import netaddr from oslo.config import cfg import pecan @@ -106,6 +108,20 @@ class VersionSelectorApplication(object): return self.v2(environ, start_response) +def get_server_cls(host): + """Return an appropriate WSGI server class base on provided host + + :param host: The listen host for the ceilometer API server. + """ + server_cls = simple_server.WSGIServer + if netaddr.valid_ipv6(host): + # NOTE(dzyu) make sure use IPv6 sockets if host is in IPv6 pattern + if getattr(server_cls, 'address_family') == socket.AF_INET: + class server_cls(server_cls): + address_family = socket.AF_INET6 + return server_cls + + def start(): service.prepare_service() @@ -114,7 +130,8 @@ def start(): # Create the WSGI server and start it host, port = cfg.CONF.api.host, cfg.CONF.api.port - srv = simple_server.make_server(host, port, root) + server_cls = get_server_cls(host) + srv = simple_server.make_server(host, port, root, server_cls) LOG.info(_('Starting server in PID %s') % os.getpid()) LOG.info(_("Configuration:")) diff --git a/ceilometer/tests/api/test_app.py b/ceilometer/tests/api/test_app.py new file mode 100644 index 000000000..b7d9b5eb1 --- /dev/null +++ b/ceilometer/tests/api/test_app.py @@ -0,0 +1,44 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2014 IBM Corp. +# 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. + +import socket + +from oslo.config import cfg + +from ceilometer.api import app +from ceilometer.openstack.common.fixture import config +from ceilometer.tests import base + + +class TestApp(base.BaseTestCase): + + def setUp(self): + super(TestApp, self).setUp() + self.CONF = self.useFixture(config.Config()).conf + + def test_WSGI_address_family(self): + self.CONF.set_override('host', '::', group='api') + server_cls = app.get_server_cls(cfg.CONF.api.host) + self.assertEqual(server_cls.address_family, socket.AF_INET6) + + self.CONF.set_override('host', '127.0.0.1', group='api') + server_cls = app.get_server_cls(cfg.CONF.api.host) + self.assertEqual(server_cls.address_family, socket.AF_INET) + + self.CONF.set_override('host', 'ddddd', group='api') + server_cls = app.get_server_cls(cfg.CONF.api.host) + self.assertEqual(server_cls.address_family, socket.AF_INET) diff --git a/requirements.txt b/requirements.txt index 7b6c237fc..162e994be 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,6 +12,7 @@ kombu>=2.4.8 lockfile>=0.8 lxml>=2.3 msgpack-python +netaddr>=0.7.6 oslo.config>=1.2.0 oslo.vmware pbr>=0.6,<1.0