Use ksa adapter for neutron client
nova.network.neutronv2.api.get_client now uses the common get_ksa_adapter utility to create an Adapter from common keystoneauth1 configuration options if the legacy [neutron] config option ``url`` is not specified. As part of blueprint use-ksa-adapter-for-endpoints, this provides a consistent mechanism for endpoint communication from Nova. Change-Id: I41724a612a5f3eabd504f3eaa9d2f9d141ca3f69 Partial-Implements: bp use-ksa-adapter-for-endpoints
This commit is contained in:
parent
9519601401
commit
6cde77ebba
@ -16,6 +16,10 @@
|
|||||||
from keystoneauth1 import loading as ks_loading
|
from keystoneauth1 import loading as ks_loading
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
|
||||||
|
from nova.conf import utils as confutils
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_SERVICE_TYPE = 'network'
|
||||||
NEUTRON_GROUP = 'neutron'
|
NEUTRON_GROUP = 'neutron'
|
||||||
|
|
||||||
neutron_group = cfg.OptGroup(
|
neutron_group = cfg.OptGroup(
|
||||||
@ -27,7 +31,15 @@ Configuration options for neutron (network connectivity as a service).
|
|||||||
|
|
||||||
neutron_opts = [
|
neutron_opts = [
|
||||||
cfg.URIOpt('url',
|
cfg.URIOpt('url',
|
||||||
default='http://127.0.0.1:9696',
|
sample_default='http://127.0.0.1:9696',
|
||||||
|
deprecated_for_removal=True,
|
||||||
|
deprecated_since='17.0.0',
|
||||||
|
deprecated_reason='Endpoint lookup uses the service catalog via '
|
||||||
|
'common keystoneauth1 Adapter configuration '
|
||||||
|
'options. In the current release, "url" will '
|
||||||
|
'override this behavior, but will be ignored and/or '
|
||||||
|
'removed in a future release. To achieve the same '
|
||||||
|
'result, use the endpoint_override option instead.',
|
||||||
help="""
|
help="""
|
||||||
This option specifies the URL for connecting to Neutron.
|
This option specifies the URL for connecting to Neutron.
|
||||||
|
|
||||||
@ -36,18 +48,6 @@ Possible values:
|
|||||||
* Any valid URL that points to the Neutron API service is appropriate here.
|
* Any valid URL that points to the Neutron API service is appropriate here.
|
||||||
This typically matches the URL returned for the 'network' service type
|
This typically matches the URL returned for the 'network' service type
|
||||||
from the Keystone service catalog.
|
from the Keystone service catalog.
|
||||||
"""),
|
|
||||||
cfg.StrOpt('region_name',
|
|
||||||
default='RegionOne',
|
|
||||||
help="""
|
|
||||||
Region name for connecting to Neutron in admin context.
|
|
||||||
|
|
||||||
This option is used in multi-region setups. If there are two Neutron
|
|
||||||
servers running in two regions in two different machines, then two
|
|
||||||
services need to be created in Keystone with two different regions and
|
|
||||||
associate corresponding endpoints to those services. When requests are made
|
|
||||||
to Keystone, the Keystone service uses the region_name to determine the
|
|
||||||
region the request is coming from.
|
|
||||||
"""),
|
"""),
|
||||||
cfg.StrOpt('ovs_bridge',
|
cfg.StrOpt('ovs_bridge',
|
||||||
default='br-int',
|
default='br-int',
|
||||||
@ -111,8 +111,11 @@ ALL_OPTS = (neutron_opts + metadata_proxy_opts)
|
|||||||
def register_opts(conf):
|
def register_opts(conf):
|
||||||
conf.register_group(neutron_group)
|
conf.register_group(neutron_group)
|
||||||
conf.register_opts(ALL_OPTS, group=neutron_group)
|
conf.register_opts(ALL_OPTS, group=neutron_group)
|
||||||
ks_loading.register_session_conf_options(conf, NEUTRON_GROUP)
|
# NOTE(efried): We don't pass `url` as a deprecated opt because that would
|
||||||
ks_loading.register_auth_conf_options(conf, NEUTRON_GROUP)
|
# make CONF.neutron.url indistinguishable from
|
||||||
|
# CONF.neutron.endpoint_override in the code, and we need to be able to use
|
||||||
|
# the former to trigger the legacy behavior.
|
||||||
|
confutils.register_ksa_opts(conf, neutron_group, DEFAULT_SERVICE_TYPE)
|
||||||
|
|
||||||
|
|
||||||
def list_opts():
|
def list_opts():
|
||||||
@ -123,5 +126,6 @@ def list_opts():
|
|||||||
ks_loading.get_auth_common_conf_options() +
|
ks_loading.get_auth_common_conf_options() +
|
||||||
ks_loading.get_auth_plugin_conf_options('password') +
|
ks_loading.get_auth_plugin_conf_options('password') +
|
||||||
ks_loading.get_auth_plugin_conf_options('v2password') +
|
ks_loading.get_auth_plugin_conf_options('v2password') +
|
||||||
ks_loading.get_auth_plugin_conf_options('v3password'))
|
ks_loading.get_auth_plugin_conf_options('v3password') +
|
||||||
|
confutils.get_ksa_adapter_opts(DEFAULT_SERVICE_TYPE))
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ from nova.pci import whitelist as pci_whitelist
|
|||||||
from nova.policies import servers as servers_policies
|
from nova.policies import servers as servers_policies
|
||||||
from nova import profiler
|
from nova import profiler
|
||||||
from nova import service_auth
|
from nova import service_auth
|
||||||
|
from nova import utils
|
||||||
|
|
||||||
CONF = nova.conf.CONF
|
CONF = nova.conf.CONF
|
||||||
|
|
||||||
@ -159,12 +160,34 @@ def get_client(context, admin=False):
|
|||||||
# an admin token so log an error
|
# an admin token so log an error
|
||||||
raise exception.Unauthorized()
|
raise exception.Unauthorized()
|
||||||
|
|
||||||
return ClientWrapper(
|
client_args = dict(session=_SESSION,
|
||||||
clientv20.Client(session=_SESSION,
|
|
||||||
auth=auth_plugin,
|
auth=auth_plugin,
|
||||||
|
global_request_id=context.global_request_id)
|
||||||
|
|
||||||
|
if CONF.neutron.url:
|
||||||
|
# TODO(efried): Remove in Rocky
|
||||||
|
client_args = dict(client_args,
|
||||||
endpoint_override=CONF.neutron.url,
|
endpoint_override=CONF.neutron.url,
|
||||||
region_name=CONF.neutron.region_name,
|
# NOTE(efried): The legacy behavior was to default
|
||||||
global_request_id=context.global_id),
|
# region_name in the conf.
|
||||||
|
region_name=CONF.neutron.region_name or 'RegionOne')
|
||||||
|
else:
|
||||||
|
# The new way
|
||||||
|
# NOTE(efried): We build an adapter
|
||||||
|
# to pull conf options
|
||||||
|
# to pass to neutronclient
|
||||||
|
# which uses them to build an Adapter.
|
||||||
|
# This should be unwound at some point.
|
||||||
|
adap = utils.get_ksa_adapter(
|
||||||
|
'network', ksa_auth=auth_plugin, ksa_session=_SESSION)
|
||||||
|
client_args = dict(client_args,
|
||||||
|
service_type=adap.service_type,
|
||||||
|
service_name=adap.service_name,
|
||||||
|
interface=adap.interface,
|
||||||
|
region_name=adap.region_name,
|
||||||
|
endpoint_override=adap.endpoint_override)
|
||||||
|
|
||||||
|
return ClientWrapper(clientv20.Client(**client_args),
|
||||||
admin=admin or context.is_admin)
|
admin=admin or context.is_admin)
|
||||||
|
|
||||||
|
|
||||||
|
@ -122,6 +122,36 @@ class TestNeutronClient(test.NoDBTestCase):
|
|||||||
super(TestNeutronClient, self).setUp()
|
super(TestNeutronClient, self).setUp()
|
||||||
neutronapi.reset_state()
|
neutronapi.reset_state()
|
||||||
|
|
||||||
|
def test_ksa_adapter_loading_defaults(self):
|
||||||
|
"""No 'url' triggers ksa loading path with defaults."""
|
||||||
|
my_context = context.RequestContext('userid',
|
||||||
|
uuids.my_tenant,
|
||||||
|
auth_token='token')
|
||||||
|
cl = neutronapi.get_client(my_context)
|
||||||
|
self.assertEqual('network', cl.httpclient.service_type)
|
||||||
|
self.assertIsNone(cl.httpclient.service_name)
|
||||||
|
self.assertEqual(['internal', 'public'], cl.httpclient.interface)
|
||||||
|
self.assertIsNone(cl.httpclient.region_name)
|
||||||
|
self.assertIsNone(cl.httpclient.endpoint_override)
|
||||||
|
|
||||||
|
def test_ksa_adapter_loading(self):
|
||||||
|
"""Test ksa loading path with specified values."""
|
||||||
|
self.flags(group='neutron',
|
||||||
|
service_type='st',
|
||||||
|
service_name='sn',
|
||||||
|
valid_interfaces='admin',
|
||||||
|
region_name='RegionTwo',
|
||||||
|
endpoint_override='eo')
|
||||||
|
my_context = context.RequestContext('userid',
|
||||||
|
uuids.my_tenant,
|
||||||
|
auth_token='token')
|
||||||
|
cl = neutronapi.get_client(my_context)
|
||||||
|
self.assertEqual('st', cl.httpclient.service_type)
|
||||||
|
self.assertEqual('sn', cl.httpclient.service_name)
|
||||||
|
self.assertEqual(['admin'], cl.httpclient.interface)
|
||||||
|
self.assertEqual('RegionTwo', cl.httpclient.region_name)
|
||||||
|
self.assertEqual('eo', cl.httpclient.endpoint_override)
|
||||||
|
|
||||||
def test_withtoken(self):
|
def test_withtoken(self):
|
||||||
self.flags(url='http://anyhost/', group='neutron')
|
self.flags(url='http://anyhost/', group='neutron')
|
||||||
self.flags(timeout=30, group='neutron')
|
self.flags(timeout=30, group='neutron')
|
||||||
@ -131,8 +161,9 @@ class TestNeutronClient(test.NoDBTestCase):
|
|||||||
cl = neutronapi.get_client(my_context)
|
cl = neutronapi.get_client(my_context)
|
||||||
|
|
||||||
self.assertEqual(CONF.neutron.url, cl.httpclient.endpoint_override)
|
self.assertEqual(CONF.neutron.url, cl.httpclient.endpoint_override)
|
||||||
self.assertEqual(my_context.auth_token,
|
# Specifying 'url' defaults 'region_name'
|
||||||
cl.httpclient.auth.auth_token)
|
self.assertEqual('RegionOne', cl.httpclient.region_name)
|
||||||
|
self.assertEqual(my_context.auth_token, cl.httpclient.auth.auth_token)
|
||||||
self.assertEqual(CONF.neutron.timeout, cl.httpclient.session.timeout)
|
self.assertEqual(CONF.neutron.timeout, cl.httpclient.session.timeout)
|
||||||
|
|
||||||
def test_withouttoken(self):
|
def test_withouttoken(self):
|
||||||
|
15
releasenotes/notes/neutron-via-ksa-9f386b09cff98a9e.yaml
Normal file
15
releasenotes/notes/neutron-via-ksa-9f386b09cff98a9e.yaml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
upgrade:
|
||||||
|
- |
|
||||||
|
Nova now uses keystoneauth1 configuration to set up communication with the
|
||||||
|
network service. Use keystoneauth1 loading parameters for Adapter setup in
|
||||||
|
the ``[neutron]`` conf section (auth and Session options continue to work
|
||||||
|
as before). Of note:
|
||||||
|
|
||||||
|
* Legacy option ``url`` is deprecated and replaced by
|
||||||
|
``endpoint_override``. This should not need to be specified if an
|
||||||
|
appropriate service catalog entry exists for the network service.
|
||||||
|
* When ``url`` is not used, ``region_name`` no longer defaults to
|
||||||
|
``RegionOne``.
|
||||||
|
* In Queens, specifying ``url`` will trigger the legacy behavior. The
|
||||||
|
``url`` option will be removed in Rocky.
|
Loading…
Reference in New Issue
Block a user