diff --git a/example.conf b/example.conf index e75738721..5b5f5c9fa 100644 --- a/example.conf +++ b/example.conf @@ -86,25 +86,36 @@ # From ironic_inspector # -# Keystone authentication endpoint. (string value) +# Keystone authentication endpoint for accessing Ironic API. Use +# [keystone_authtoken]/auth_uri for keystone authentication. (string +# value) # Deprecated group/name - [discoverd]/os_auth_url -#os_auth_url = http://127.0.0.1:5000/v2.0 +#os_auth_url = -# User name for accessing Keystone and Ironic API. (string value) +# User name for accessing Ironic API. Use +# [keystone_authtoken]/admin_user for keystone authentication. (string +# value) # Deprecated group/name - [discoverd]/os_username #os_username = -# Password for accessing Keystone and Ironic API. (string value) +# Password for accessing Ironic API. Use +# [keystone_authtoken]/admin_password for keystone authentication. +# (string value) # Deprecated group/name - [discoverd]/os_password #os_password = -# Tenant name for accessing Keystone and Ironic API. (string value) +# Tenant name for accessing Ironic API. Use +# [keystone_authtoken]/admin_tenant_name for keystone authentication. +# (string value) # Deprecated group/name - [discoverd]/os_tenant_name #os_tenant_name = -# Keystone admin endpoint. (string value) +# Keystone admin endpoint. DEPRECATED: use +# [keystone_authtoken]/identity_uri. (string value) # Deprecated group/name - [discoverd]/identity_uri -#identity_uri = http://127.0.0.1:35357 +# This option is deprecated for removal. +# Its value may be silently ignored in the future. +#identity_uri = # Number of attempts to do when trying to connect to Ironic on start # up. (integer value) @@ -126,6 +137,175 @@ #ironic_url = http://localhost:6385/ +[keystone_authtoken] + +# +# From keystonemiddleware.auth_token +# + +# Complete public Identity API endpoint. (string value) +#auth_uri = + +# API version of the admin Identity API endpoint. (string value) +#auth_version = + +# Do not handle authorization requests within the middleware, but +# delegate the authorization decision to downstream WSGI components. +# (boolean value) +#delay_auth_decision = false + +# Request timeout value for communicating with Identity API server. +# (integer value) +#http_connect_timeout = + +# How many times are we trying to reconnect when communicating with +# Identity API Server. (integer value) +#http_request_max_retries = 3 + +# Env key for the swift cache. (string value) +#cache = + +# Required if identity server requires client certificate (string +# value) +#certfile = + +# Required if identity server requires client certificate (string +# value) +#keyfile = + +# A PEM encoded Certificate Authority to use when verifying HTTPs +# connections. Defaults to system CAs. (string value) +#cafile = + +# Verify HTTPS connections. (boolean value) +#insecure = false + +# Directory used to cache files related to PKI tokens. (string value) +#signing_dir = + +# Optionally specify a list of memcached server(s) to use for caching. +# If left undefined, tokens will instead be cached in-process. (list +# value) +# Deprecated group/name - [DEFAULT]/memcache_servers +#memcached_servers = + +# In order to prevent excessive effort spent validating tokens, the +# middleware caches previously-seen tokens for a configurable duration +# (in seconds). Set to -1 to disable caching completely. (integer +# value) +#token_cache_time = 300 + +# Determines the frequency at which the list of revoked tokens is +# retrieved from the Identity service (in seconds). A high number of +# revocation events combined with a low cache duration may +# significantly reduce performance. (integer value) +#revocation_cache_time = 10 + +# (Optional) If defined, indicate whether token data should be +# authenticated or authenticated and encrypted. Acceptable values are +# MAC or ENCRYPT. If MAC, token data is authenticated (with HMAC) in +# the cache. If ENCRYPT, token data is encrypted and authenticated in +# the cache. If the value is not one of these options or empty, +# auth_token will raise an exception on initialization. (string value) +#memcache_security_strategy = + +# (Optional, mandatory if memcache_security_strategy is defined) This +# string is used for key derivation. (string value) +#memcache_secret_key = + +# (Optional) Number of seconds memcached server is considered dead +# before it is tried again. (integer value) +#memcache_pool_dead_retry = 300 + +# (Optional) Maximum total number of open connections to every +# memcached server. (integer value) +#memcache_pool_maxsize = 10 + +# (Optional) Socket timeout in seconds for communicating with a +# memcached server. (integer value) +#memcache_pool_socket_timeout = 3 + +# (Optional) Number of seconds a connection to memcached is held +# unused in the pool before it is closed. (integer value) +#memcache_pool_unused_timeout = 60 + +# (Optional) Number of seconds that an operation will wait to get a +# memcached client connection from the pool. (integer value) +#memcache_pool_conn_get_timeout = 10 + +# (Optional) Use the advanced (eventlet safe) memcached client pool. +# The advanced pool will only work under python 2.x. (boolean value) +#memcache_use_advanced_pool = false + +# (Optional) Indicate whether to set the X-Service-Catalog header. If +# False, middleware will not ask for service catalog on token +# validation and will not set the X-Service-Catalog header. (boolean +# value) +#include_service_catalog = true + +# Used to control the use and type of token binding. Can be set to: +# "disabled" to not check token binding. "permissive" (default) to +# validate binding information if the bind type is of a form known to +# the server and ignore it if not. "strict" like "permissive" but if +# the bind type is unknown the token will be rejected. "required" any +# form of token binding is needed to be allowed. Finally the name of a +# binding method that must be present in tokens. (string value) +#enforce_token_bind = permissive + +# If true, the revocation list will be checked for cached tokens. This +# requires that PKI tokens are configured on the identity server. +# (boolean value) +#check_revocations_for_cached = false + +# Hash algorithms to use for hashing PKI tokens. This may be a single +# algorithm or multiple. The algorithms are those supported by Python +# standard hashlib.new(). The hashes will be tried in the order given, +# so put the preferred one first for performance. The result of the +# first hash will be stored in the cache. This will typically be set +# to multiple values only while migrating from a less secure algorithm +# to a more secure one. Once all the old tokens are expired this +# option should be set to a single value for better performance. (list +# value) +#hash_algorithms = md5 + +# Prefix to prepend at the beginning of the path. Deprecated, use +# identity_uri. (string value) +#auth_admin_prefix = + +# Host providing the admin Identity API endpoint. Deprecated, use +# identity_uri. (string value) +#auth_host = 127.0.0.1 + +# Port of the admin Identity API endpoint. Deprecated, use +# identity_uri. (integer value) +#auth_port = 35357 + +# Protocol of the admin Identity API endpoint (http or https). +# Deprecated, use identity_uri. (string value) +#auth_protocol = https + +# Complete admin Identity API endpoint. This should specify the +# unversioned root endpoint e.g. https://localhost:35357/ (string +# value) +#identity_uri = + +# This option is deprecated and may be removed in a future release. +# Single shared secret with the Keystone configuration used for +# bootstrapping a Keystone installation, or otherwise bypassing the +# normal authentication process. This option should not be used, use +# `admin_user` and `admin_password` instead. (string value) +#admin_token = + +# Service username. (string value) +#admin_user = + +# Service user password. (string value) +#admin_password = + +# Service tenant name. (string value) +#admin_tenant_name = admin + + [processing] # diff --git a/ironic_inspector/conf.py b/ironic_inspector/conf.py index 35d00c92a..ca9f59ff7 100644 --- a/ironic_inspector/conf.py +++ b/ironic_inspector/conf.py @@ -20,26 +20,36 @@ VALID_KEEP_PORTS_VALUES = ('all', 'present', 'added') IRONIC_OPTS = [ cfg.StrOpt('os_auth_url', - default='http://127.0.0.1:5000/v2.0', - help='Keystone authentication endpoint.', + default='', + help='Keystone authentication endpoint for accessing Ironic ' + 'API. Use [keystone_authtoken]/auth_uri for keystone ' + 'authentication.', deprecated_group='discoverd'), cfg.StrOpt('os_username', default='', - help='User name for accessing Keystone and Ironic API.', + help='User name for accessing Ironic API. ' + 'Use [keystone_authtoken]/admin_user for keystone ' + 'authentication.', deprecated_group='discoverd'), cfg.StrOpt('os_password', default='', - help='Password for accessing Keystone and Ironic API.', + help='Password for accessing Ironic API. ' + 'Use [keystone_authtoken]/admin_password for keystone ' + 'authentication.', secret=True, deprecated_group='discoverd'), cfg.StrOpt('os_tenant_name', default='', - help='Tenant name for accessing Keystone and Ironic API.', + help='Tenant name for accessing Ironic API. ' + 'Use [keystone_authtoken]/admin_tenant_name for keystone ' + 'authentication.', deprecated_group='discoverd'), cfg.StrOpt('identity_uri', - default='http://127.0.0.1:35357', - help='Keystone admin endpoint.', - deprecated_group='discoverd'), + default='', + help='Keystone admin endpoint. ' + 'DEPRECATED: use [keystone_authtoken]/identity_uri.', + deprecated_group='discoverd', + deprecated_for_removal=True), cfg.IntOpt('ironic_retry_attempts', default=5, help='Number of attempts to do when trying to connect to ' diff --git a/ironic_inspector/test/test_utils.py b/ironic_inspector/test/test_utils.py index b4aee67d8..fa0a54d13 100644 --- a/ironic_inspector/test/test_utils.py +++ b/ironic_inspector/test/test_utils.py @@ -36,20 +36,57 @@ class TestCheckAuth(base.BaseTest): @mock.patch.object(auth_token, 'AuthProtocol') def test_middleware(self, mock_auth): - CONF.set_override('os_username', 'admin', 'ironic') - CONF.set_override('os_tenant_name', 'admin', 'ironic') - CONF.set_override('os_password', 'password', 'ironic') + CONF.set_override('admin_user', 'admin', 'keystone_authtoken') + CONF.set_override('admin_tenant_name', 'admin', 'keystone_authtoken') + CONF.set_override('admin_password', 'password', 'keystone_authtoken') + CONF.set_override('auth_uri', 'http://127.0.0.1:5000/v2.0', + 'keystone_authtoken') + CONF.set_override('identity_uri', 'http://127.0.0.1:35357', + 'keystone_authtoken') app = mock.Mock(wsgi_app=mock.sentinel.app) utils.add_auth_middleware(app) - mock_auth.assert_called_once_with( - mock.sentinel.app, - {'admin_user': 'admin', 'admin_tenant_name': 'admin', - 'admin_password': 'password', 'delay_auth_decision': True, - 'auth_uri': 'http://127.0.0.1:5000/v2.0', - 'identity_uri': 'http://127.0.0.1:35357'} - ) + call_args = mock_auth.call_args_list[0] + args = call_args[0] + self.assertEqual(mock.sentinel.app, args[0]) + args1 = args[1] + + self.assertEqual('admin', args1['admin_user']) + self.assertEqual('admin', args1['admin_tenant_name']) + self.assertEqual('password', args1['admin_password']) + self.assertEqual(True, args1['delay_auth_decision']) + self.assertEqual('http://127.0.0.1:5000/v2.0', args1['auth_uri']) + self.assertEqual('http://127.0.0.1:35357', args1['identity_uri']) + + @mock.patch.object(auth_token, 'AuthProtocol') + def test_add_auth_middleware_with_deprecated_items(self, mock_auth): + CONF.set_override('os_password', 'os_password', 'ironic') + CONF.set_override('admin_password', 'admin_password', + 'keystone_authtoken') + CONF.set_override('os_username', 'os_username', 'ironic') + CONF.set_override('admin_user', 'admin_user', 'keystone_authtoken') + CONF.set_override('os_auth_url', 'os_auth_url', 'ironic') + CONF.set_override('auth_uri', 'auth_uri', 'keystone_authtoken') + CONF.set_override('os_tenant_name', 'os_tenant_name', 'ironic') + CONF.set_override('admin_tenant_name', 'admin_tenant_name', + 'keystone_authtoken') + CONF.set_override('identity_uri', 'identity_uri_ironic', 'ironic') + CONF.set_override('identity_uri', 'identity_uri', 'keystone_authtoken') + + app = mock.Mock(wsgi_app=mock.sentinel.app) + utils.add_auth_middleware(app) + + call_args = mock_auth.call_args_list[0] + args = call_args[0] + self.assertEqual(mock.sentinel.app, args[0]) + args1 = args[1] + self.assertEqual('os_password', args1['admin_password']) + self.assertEqual('os_username', args1['admin_user']) + self.assertEqual('os_auth_url', args1['auth_uri']) + self.assertEqual('os_tenant_name', args1['admin_tenant_name']) + self.assertTrue(args1['delay_auth_decision']) + self.assertEqual('identity_uri_ironic', args1['identity_uri']) def test_ok(self): request = mock.Mock(headers={'X-Identity-Status': 'Confirmed', diff --git a/ironic_inspector/utils.py b/ironic_inspector/utils.py index 65a48c38d..9cfac4bda 100644 --- a/ironic_inspector/utils.py +++ b/ironic_inspector/utils.py @@ -72,12 +72,31 @@ def add_auth_middleware(app): :param app: application. """ - auth_conf = dict({'admin_password': CONF.ironic.os_password, - 'admin_user': CONF.ironic.os_username, - 'auth_uri': CONF.ironic.os_auth_url, - 'admin_tenant_name': CONF.ironic.os_tenant_name}) + auth_conf = dict(CONF.keystone_authtoken) + # These items should only be used for accessing Ironic API. + # For keystonemiddleware's authentication, + # keystone_authtoken's items will be used and + # these items will be unsupported. + # [ironic]/os_password + # [ironic]/os_username + # [ironic]/os_auth_url + # [ironic]/os_tenant_name + auth_conf.update({'admin_password': + CONF.ironic.os_password or + CONF.keystone_authtoken.admin_password, + 'admin_user': + CONF.ironic.os_username or + CONF.keystone_authtoken.admin_user, + 'auth_uri': + CONF.ironic.os_auth_url or + CONF.keystone_authtoken.auth_uri, + 'admin_tenant_name': + CONF.ironic.os_tenant_name or + CONF.keystone_authtoken.admin_tenant_name, + 'identity_uri': + CONF.ironic.identity_uri or + CONF.keystone_authtoken.identity_uri}) auth_conf['delay_auth_decision'] = True - auth_conf['identity_uri'] = CONF.ironic.identity_uri app.wsgi_app = auth_token.AuthProtocol(app.wsgi_app, auth_conf) diff --git a/tox.ini b/tox.ini index b75b01754..ff44b5db5 100644 --- a/tox.ini +++ b/tox.ini @@ -42,4 +42,5 @@ commands = commands = oslo-config-generator \ --output-file example.conf \ - --namespace ironic_inspector + --namespace ironic_inspector \ + --namespace keystonemiddleware.auth_token