Add keystoneauth adapters
Inspector sets API urls for ironic and swift from the config. The better way would be to discovery them from the keystone catalog. Supporting this requires to register keystoneauth adapter options to all config sections for service clients auth. swiftclient still does not support adapter session client, so pass all options from adapter explicitly. New options were added 'service_type`, `service_name`, `region_name` `endpoint_override`, `interfaces`. Related-Bug: #1699547 Change-Id: I2e7ec02fdeeea21ef43136ddeabc98d499a8ba7f Co-Authored-By: Anton Arefiev <aarefiev@mirantis.com>
This commit is contained in:
parent
b88823a771
commit
918775cb01
@ -195,7 +195,7 @@ function inspector_configure_auth_for {
|
||||
inspector_iniset $1 user_domain_id default
|
||||
inspector_iniset $1 project_domain_id default
|
||||
inspector_iniset $1 cafile $SSL_BUNDLE_FILE
|
||||
inspector_iniset $1 os_region $REGION_NAME
|
||||
inspector_iniset $1 region_name $REGION_NAME
|
||||
}
|
||||
|
||||
function is_dnsmasq_filter_required {
|
||||
|
161
example.conf
161
example.conf
@ -15,7 +15,9 @@
|
||||
# Authentication method used on the ironic-inspector API. Either
|
||||
# "noauth" or "keystone" are currently valid options. "noauth" will
|
||||
# disable all authentication. (string value)
|
||||
# Allowed values: keystone, noauth
|
||||
# Possible values:
|
||||
# keystone - <No description provided>
|
||||
# noauth - <No description provided>
|
||||
#auth_strategy = keystone
|
||||
|
||||
# Timeout after which introspection is considered failed, set to 0 to
|
||||
@ -414,8 +416,16 @@
|
||||
# Authentication URL (string value)
|
||||
#auth_url = <None>
|
||||
|
||||
# Method to use for authentication: noauth or keystone. (string value)
|
||||
# Allowed values: keystone, noauth
|
||||
# DEPRECATED: Method to use for authentication: noauth or keystone.
|
||||
# (string value)
|
||||
# Possible values:
|
||||
# keystone - <No description provided>
|
||||
# noauth - <No description provided>
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: Use [ironic]/auth_type, for noauth case set
|
||||
# [ironic]/auth_type to `none` and specify ironic API URL via
|
||||
# [ironic]/endpoint_override option.
|
||||
#auth_strategy = keystone
|
||||
|
||||
# Authentication type to load (string value)
|
||||
@ -445,28 +455,60 @@
|
||||
# Domain name to scope to (string value)
|
||||
#domain_name = <None>
|
||||
|
||||
# Always use this endpoint URL for requests for this client. NOTE: The
|
||||
# unversioned endpoint should be specified here; to request a
|
||||
# particular API version, use the `version`, `min-version`, and/or
|
||||
# `max-version` options. (string value)
|
||||
#endpoint_override = <None>
|
||||
|
||||
# Verify HTTPS connections. (boolean value)
|
||||
#insecure = false
|
||||
|
||||
# Ironic API URL, used to set Ironic API URL when auth_strategy option
|
||||
# is noauth to work with standalone Ironic without keystone. (string
|
||||
# value)
|
||||
# DEPRECATED: Ironic API URL, used to set Ironic API URL when
|
||||
# auth_strategy option is noauth or auth_type is "none" to work with
|
||||
# standalone Ironic without keystone. (string value)
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: Use [ironic]/endpoint_override option to set a specific
|
||||
# ironic API url.
|
||||
#ironic_url = http://localhost:6385/
|
||||
|
||||
# PEM encoded client certificate key file (string value)
|
||||
#keyfile = <None>
|
||||
|
||||
# The maximum major version of a given API, intended to be used as the
|
||||
# upper bound of a range with min_version. Mutually exclusive with
|
||||
# version. (string value)
|
||||
#max_version = <None>
|
||||
|
||||
# Maximum number of retries in case of conflict error (HTTP 409).
|
||||
# (integer value)
|
||||
#max_retries = 30
|
||||
|
||||
# Ironic endpoint type. (string value)
|
||||
# The minimum major version of a given API, intended to be used as the
|
||||
# lower bound of a range with max_version. Mutually exclusive with
|
||||
# version. If min_version is given with no max_version it is as if max
|
||||
# version is "latest". (string value)
|
||||
#min_version = <None>
|
||||
|
||||
# DEPRECATED: Ironic endpoint type. (string value)
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: Use [ironic]/valid_interfaces option to specify endpoint
|
||||
# interfaces.
|
||||
#os_endpoint_type = internalURL
|
||||
|
||||
# Keystone region used to get Ironic endpoints. (string value)
|
||||
# DEPRECATED: Keystone region used to get Ironic endpoints. (string
|
||||
# value)
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: Use [ironic]/region_name option instead to configure region.
|
||||
#os_region = <None>
|
||||
|
||||
# Ironic service type. (string value)
|
||||
# DEPRECATED: Ironic service type. (string value)
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: Use [ironic]/service_type option to set a specific type.
|
||||
#os_service_type = baremetal
|
||||
|
||||
# User's password (string value)
|
||||
@ -486,10 +528,19 @@
|
||||
# Deprecated group/name - [ironic]/tenant_name
|
||||
#project_name = <None>
|
||||
|
||||
# The default region_name for endpoint URL discovery. (string value)
|
||||
#region_name = <None>
|
||||
|
||||
# Interval between retries in case of conflict error (HTTP 409).
|
||||
# (integer value)
|
||||
#retry_interval = 2
|
||||
|
||||
# The default service_name for endpoint URL discovery. (string value)
|
||||
#service_name = <None>
|
||||
|
||||
# The default service_type for endpoint URL discovery. (string value)
|
||||
#service_type = baremetal
|
||||
|
||||
# Tenant ID (string value)
|
||||
#tenant_id = <None>
|
||||
|
||||
@ -515,6 +566,15 @@
|
||||
# Deprecated group/name - [ironic]/user_name
|
||||
#username = <None>
|
||||
|
||||
# List of interfaces, in order of preference, for endpoint URL. (list
|
||||
# value)
|
||||
#valid_interfaces = internal,public
|
||||
|
||||
# Minimum Major API version within a given Major API version for
|
||||
# endpoint URL discovery. Mutually exclusive with min_version and
|
||||
# max_version (string value)
|
||||
#version = <None>
|
||||
|
||||
|
||||
[keystone_authtoken]
|
||||
|
||||
@ -627,7 +687,10 @@
|
||||
# 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)
|
||||
# Allowed values: None, MAC, ENCRYPT
|
||||
# Possible values:
|
||||
# None - <No description provided>
|
||||
# MAC - <No description provided>
|
||||
# ENCRYPT - <No description provided>
|
||||
#memcache_security_strategy = None
|
||||
|
||||
# (Optional, mandatory if memcache_security_strategy is defined) This
|
||||
@ -725,6 +788,14 @@
|
||||
# From oslo.policy
|
||||
#
|
||||
|
||||
# This option controls whether or not to enforce scope when evaluating
|
||||
# policies. If ``True``, the scope of the token used in the request is
|
||||
# compared to the ``scope_types`` of the policy being enforced. If the
|
||||
# scopes do not match, an ``InvalidScope`` exception will be raised.
|
||||
# If ``False``, a message will be logged informing operators that
|
||||
# policies are being invoked with mismatching scope. (boolean value)
|
||||
#enforce_scope = false
|
||||
|
||||
# The file that defines policies. (string value)
|
||||
#policy_file = policy.json
|
||||
|
||||
@ -741,7 +812,9 @@
|
||||
|
||||
# Content Type to send and receive data for REST based policy check
|
||||
# (string value)
|
||||
# Allowed values: application/x-www-form-urlencoded, application/json
|
||||
# Possible values:
|
||||
# application/x-www-form-urlencoded - <No description provided>
|
||||
# application/json - <No description provided>
|
||||
#remote_content_type = application/x-www-form-urlencoded
|
||||
|
||||
# server identity verification for REST based policy check (boolean
|
||||
@ -783,14 +856,21 @@
|
||||
# IP addresses), pxe (only MAC address of NIC node PXE booted from,
|
||||
# falls back to "active" if PXE MAC is not supplied by the ramdisk).
|
||||
# (string value)
|
||||
# Allowed values: all, active, pxe, disabled
|
||||
# Possible values:
|
||||
# all - <No description provided>
|
||||
# active - <No description provided>
|
||||
# pxe - <No description provided>
|
||||
# disabled - <No description provided>
|
||||
#add_ports = pxe
|
||||
|
||||
# Which ports (already present on a node) to keep after introspection.
|
||||
# Possible values: all (do not delete anything), present (keep ports
|
||||
# which MACs were present in introspection data), added (keep only
|
||||
# MACs that we added during introspection). (string value)
|
||||
# Allowed values: all, present, added
|
||||
# Possible values:
|
||||
# all - <No description provided>
|
||||
# present - <No description provided>
|
||||
# added - <No description provided>
|
||||
#keep_ports = all
|
||||
|
||||
# Whether to overwrite existing values in node database. Disable this
|
||||
@ -827,7 +907,9 @@
|
||||
|
||||
# Method for storing introspection data. If set to 'none',
|
||||
# introspection data will not be stored. (string value)
|
||||
# Allowed values: none, swift
|
||||
# Possible values:
|
||||
# none - <No description provided>
|
||||
# swift - <No description provided>
|
||||
#store_data = none
|
||||
|
||||
# Name of the key to store the location of stored data in the extra
|
||||
@ -908,23 +990,50 @@
|
||||
# Domain name to scope to (string value)
|
||||
#domain_name = <None>
|
||||
|
||||
# Always use this endpoint URL for requests for this client. NOTE: The
|
||||
# unversioned endpoint should be specified here; to request a
|
||||
# particular API version, use the `version`, `min-version`, and/or
|
||||
# `max-version` options. (string value)
|
||||
#endpoint_override = <None>
|
||||
|
||||
# Verify HTTPS connections. (boolean value)
|
||||
#insecure = false
|
||||
|
||||
# PEM encoded client certificate key file (string value)
|
||||
#keyfile = <None>
|
||||
|
||||
# The maximum major version of a given API, intended to be used as the
|
||||
# upper bound of a range with min_version. Mutually exclusive with
|
||||
# version. (string value)
|
||||
#max_version = <None>
|
||||
|
||||
# Maximum number of times to retry a Swift request, before failing.
|
||||
# (integer value)
|
||||
#max_retries = 2
|
||||
|
||||
# Swift endpoint type. (string value)
|
||||
# The minimum major version of a given API, intended to be used as the
|
||||
# lower bound of a range with max_version. Mutually exclusive with
|
||||
# version. If min_version is given with no max_version it is as if max
|
||||
# version is "latest". (string value)
|
||||
#min_version = <None>
|
||||
|
||||
# DEPRECATED: Swift endpoint type. (string value)
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: Use [swift]/valid_interfaces option to specify endpoint
|
||||
# interfaces.
|
||||
#os_endpoint_type = internalURL
|
||||
|
||||
# Keystone region to get endpoint for. (string value)
|
||||
# DEPRECATED: Keystone region to get endpoint for. (string value)
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: Use [swift]/region_name option to configure region.
|
||||
#os_region = <None>
|
||||
|
||||
# Swift service type. (string value)
|
||||
# DEPRECATED: Swift service type. (string value)
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: Use [swift]/service_type option to set specific service type
|
||||
#os_service_type = object-store
|
||||
|
||||
# User's password (string value)
|
||||
@ -944,6 +1053,15 @@
|
||||
# Deprecated group/name - [swift]/tenant_name
|
||||
#project_name = <None>
|
||||
|
||||
# The default region_name for endpoint URL discovery. (string value)
|
||||
#region_name = <None>
|
||||
|
||||
# The default service_name for endpoint URL discovery. (string value)
|
||||
#service_name = <None>
|
||||
|
||||
# The default service_type for endpoint URL discovery. (string value)
|
||||
#service_type = object-store
|
||||
|
||||
# Tenant ID (string value)
|
||||
#tenant_id = <None>
|
||||
|
||||
@ -968,3 +1086,12 @@
|
||||
# Username (string value)
|
||||
# Deprecated group/name - [swift]/user_name
|
||||
#username = <None>
|
||||
|
||||
# List of interfaces, in order of preference, for endpoint URL. (list
|
||||
# value)
|
||||
#valid_interfaces = internal,public
|
||||
|
||||
# Minimum Major API version within a given Major API version for
|
||||
# endpoint URL discovery. Mutually exclusive with min_version and
|
||||
# max_version (string value)
|
||||
#version = <None>
|
||||
|
@ -82,29 +82,42 @@ def get_ipmi_address(node):
|
||||
def get_client(token=None,
|
||||
api_version=DEFAULT_IRONIC_API_VERSION): # pragma: no cover
|
||||
"""Get Ironic client instance."""
|
||||
global IRONIC_SESSION
|
||||
if not IRONIC_SESSION:
|
||||
IRONIC_SESSION = keystone.get_session('ironic')
|
||||
|
||||
args = {
|
||||
'os_ironic_api_version': api_version,
|
||||
'max_retries': CONF.ironic.max_retries,
|
||||
'retry_interval': CONF.ironic.retry_interval}
|
||||
|
||||
adapter_opts = dict()
|
||||
|
||||
# NOTE: To support standalone ironic without keystone
|
||||
# TODO(pas-ha) remove handling of deprecated opts in Rocky
|
||||
# TODO(pas-ha) rewrite when ironicclient natively supports 'none' auth
|
||||
# via sessions https://review.openstack.org/#/c/359061/
|
||||
if CONF.ironic.auth_strategy == 'noauth':
|
||||
args = {'token': 'noauth',
|
||||
'endpoint': CONF.ironic.ironic_url}
|
||||
CONF.set_override('auth_type', 'none', group='ironic')
|
||||
else:
|
||||
global IRONIC_SESSION
|
||||
if not IRONIC_SESSION:
|
||||
IRONIC_SESSION = keystone.get_session('ironic')
|
||||
# TODO(pas-ha) use service auth with incoming token
|
||||
if token is None:
|
||||
args = {'session': IRONIC_SESSION,
|
||||
'region_name': CONF.ironic.os_region}
|
||||
args['session'] = IRONIC_SESSION
|
||||
else:
|
||||
ironic_url = IRONIC_SESSION.get_endpoint(
|
||||
service_type=CONF.ironic.os_service_type,
|
||||
endpoint_type=CONF.ironic.os_endpoint_type,
|
||||
region_name=CONF.ironic.os_region
|
||||
)
|
||||
args = {'token': token,
|
||||
'endpoint': ironic_url}
|
||||
args['os_ironic_api_version'] = api_version
|
||||
args['max_retries'] = CONF.ironic.max_retries
|
||||
args['retry_interval'] = CONF.ironic.retry_interval
|
||||
return client.Client(1, **args)
|
||||
args['token'] = token
|
||||
|
||||
# TODO(pas-ha): remove handling of deprecated options in Rocky
|
||||
if CONF.ironic.os_region and not CONF.ironic.region_name:
|
||||
adapter_opts['region_name'] = CONF.ironic.os_region
|
||||
if (CONF.ironic.auth_type == 'none' and
|
||||
not CONF.ironic.endpoint_override and
|
||||
CONF.ironic.ironic_url):
|
||||
adapter_opts['endpoint_override'] = CONF.ironic.ironic_url
|
||||
|
||||
adapter = keystone.get_adapter('ironic', session=IRONIC_SESSION,
|
||||
**adapter_opts)
|
||||
endpoint = adapter.get_endpoint()
|
||||
return client.Client(1, endpoint, **args)
|
||||
|
||||
|
||||
def check_provision_state(node):
|
||||
|
@ -18,12 +18,18 @@ from oslo_config import cfg
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
DEFAULT_VALID_INTERFACES = ['internal', 'public']
|
||||
|
||||
|
||||
def register_auth_opts(group):
|
||||
# TODO(pas-ha) set default values in conf.opts.set_defaults()
|
||||
def register_auth_opts(group, service_type):
|
||||
loading.register_session_conf_options(CONF, group)
|
||||
loading.register_auth_conf_options(CONF, group)
|
||||
CONF.set_default('auth_type', default='password', group=group)
|
||||
loading.register_adapter_conf_options(CONF, group)
|
||||
CONF.set_default('valid_interfaces', DEFAULT_VALID_INTERFACES,
|
||||
group=group)
|
||||
CONF.set_default('service_type', service_type, group=group)
|
||||
|
||||
|
||||
def get_session(group):
|
||||
@ -33,8 +39,13 @@ def get_session(group):
|
||||
return session
|
||||
|
||||
|
||||
def add_auth_options(options):
|
||||
def get_adapter(group, **adapter_kwargs):
|
||||
return loading.load_adapter_from_conf_options(CONF, group,
|
||||
**adapter_kwargs)
|
||||
|
||||
|
||||
# TODO(pas-ha) set default values in conf.opts.set_defaults()
|
||||
def add_auth_options(options, service_type):
|
||||
def add_options(opts, opts_to_add):
|
||||
for new_opt in opts_to_add:
|
||||
for opt in opts:
|
||||
@ -52,5 +63,10 @@ def add_auth_options(options):
|
||||
plugin = loading.get_plugin_loader(name)
|
||||
add_options(opts, loading.get_auth_plugin_conf_options(plugin))
|
||||
add_options(opts, loading.get_session_conf_options())
|
||||
adapter_opts = loading.get_adapter_conf_options(
|
||||
include_deprecated=False)
|
||||
cfg.set_defaults(adapter_opts, service_type=service_type,
|
||||
valid_interfaces=DEFAULT_VALID_INTERFACES)
|
||||
add_options(opts, adapter_opts)
|
||||
opts.sort(key=lambda x: x.name)
|
||||
return opts
|
||||
|
@ -51,7 +51,21 @@ class SwiftAPI(object):
|
||||
if not SWIFT_SESSION:
|
||||
SWIFT_SESSION = keystone.get_session('swift')
|
||||
|
||||
self.connection = swift_client.Connection(session=SWIFT_SESSION)
|
||||
adapter_opts = dict()
|
||||
# TODO(pas-ha): remove handling deprecated options in Rocky
|
||||
if CONF.swift.os_region and not CONF.swift.region_name:
|
||||
adapter_opts['region_name'] = CONF.swift.os_region
|
||||
|
||||
adapter = keystone.get_adapter('swift', session=SWIFT_SESSION,
|
||||
**adapter_opts)
|
||||
|
||||
# TODO(pas-ha) reverse-construct SSL-related session options here
|
||||
params = {
|
||||
'os_options': {
|
||||
'object_storage_url': adapter.get_endpoint()}}
|
||||
|
||||
self.connection = swift_client.Connection(session=SWIFT_SESSION,
|
||||
**params)
|
||||
|
||||
def create_object(self, object, data, container=CONF.swift.container,
|
||||
headers=None):
|
||||
|
@ -18,27 +18,45 @@ from ironic_inspector.common import keystone
|
||||
|
||||
|
||||
IRONIC_GROUP = 'ironic'
|
||||
SERVICE_TYPE = 'baremetal'
|
||||
|
||||
|
||||
_OPTS = [
|
||||
cfg.StrOpt('os_region',
|
||||
help=_('Keystone region used to get Ironic endpoints.')),
|
||||
help=_('Keystone region used to get Ironic endpoints.'),
|
||||
deprecated_for_removal=True,
|
||||
deprecated_reason=_("Use [ironic]/region_name option instead "
|
||||
"to configure region.")),
|
||||
cfg.StrOpt('auth_strategy',
|
||||
default='keystone',
|
||||
choices=('keystone', 'noauth'),
|
||||
help=_('Method to use for authentication: noauth or '
|
||||
'keystone.')),
|
||||
'keystone.'),
|
||||
deprecated_for_removal=True,
|
||||
deprecated_reason=_("Use [ironic]/auth_type, for noauth case "
|
||||
"set [ironic]/auth_type to `none` and "
|
||||
"specify ironic API URL via "
|
||||
"[ironic]/endpoint_override option.")),
|
||||
cfg.StrOpt('ironic_url',
|
||||
default='http://localhost:6385/',
|
||||
help=_('Ironic API URL, used to set Ironic API URL when '
|
||||
'auth_strategy option is noauth to work with standalone '
|
||||
'Ironic without keystone.')),
|
||||
'auth_strategy option is noauth or auth_type is "none" '
|
||||
'to work with standalone Ironic without keystone.'),
|
||||
deprecated_for_removal=True,
|
||||
deprecated_reason=_('Use [ironic]/endpoint_override option '
|
||||
'to set a specific ironic API url.')),
|
||||
cfg.StrOpt('os_service_type',
|
||||
default='baremetal',
|
||||
help=_('Ironic service type.')),
|
||||
help=_('Ironic service type.'),
|
||||
deprecated_for_removal=True,
|
||||
deprecated_reason=_('Use [ironic]/service_type option '
|
||||
'to set a specific type.')),
|
||||
cfg.StrOpt('os_endpoint_type',
|
||||
default='internalURL',
|
||||
help=_('Ironic endpoint type.')),
|
||||
help=_('Ironic endpoint type.'),
|
||||
deprecated_for_removal=True,
|
||||
deprecated_reason=_('Use [ironic]/valid_interfaces option '
|
||||
'to specify endpoint interfaces.')),
|
||||
cfg.IntOpt('retry_interval',
|
||||
default=2,
|
||||
help=_('Interval between retries in case of conflict error '
|
||||
@ -52,8 +70,8 @@ _OPTS = [
|
||||
|
||||
def register_opts(conf):
|
||||
conf.register_opts(_OPTS, IRONIC_GROUP)
|
||||
keystone.register_auth_opts(IRONIC_GROUP)
|
||||
keystone.register_auth_opts(IRONIC_GROUP, SERVICE_TYPE)
|
||||
|
||||
|
||||
def list_opts():
|
||||
return keystone.add_auth_options(_OPTS)
|
||||
return keystone.add_auth_options(_OPTS, SERVICE_TYPE)
|
||||
|
@ -18,6 +18,7 @@ from ironic_inspector.common import keystone
|
||||
|
||||
|
||||
SWIFT_GROUP = 'swift'
|
||||
SERVICE_TYPE = 'object-store'
|
||||
|
||||
|
||||
_OPTS = [
|
||||
@ -36,19 +37,28 @@ _OPTS = [
|
||||
'objects.')),
|
||||
cfg.StrOpt('os_service_type',
|
||||
default='object-store',
|
||||
help=_('Swift service type.')),
|
||||
help=_('Swift service type.'),
|
||||
deprecated_for_removal=True,
|
||||
deprecated_reason=_('Use [swift]/service_type option '
|
||||
'to set specific service type')),
|
||||
cfg.StrOpt('os_endpoint_type',
|
||||
default='internalURL',
|
||||
help=_('Swift endpoint type.')),
|
||||
help=_('Swift endpoint type.'),
|
||||
deprecated_for_removal=True,
|
||||
deprecated_reason=_('Use [swift]/valid_interfaces option '
|
||||
'to specify endpoint interfaces.')),
|
||||
cfg.StrOpt('os_region',
|
||||
help=_('Keystone region to get endpoint for.')),
|
||||
help=_('Keystone region to get endpoint for.'),
|
||||
deprecated_for_removal=True,
|
||||
deprecated_reason=_("Use [swift]/region_name option to "
|
||||
"configure region."))
|
||||
]
|
||||
|
||||
|
||||
def register_opts(conf):
|
||||
conf.register_opts(_OPTS, SWIFT_GROUP)
|
||||
keystone.register_auth_opts(SWIFT_GROUP)
|
||||
keystone.register_auth_opts(SWIFT_GROUP, SERVICE_TYPE)
|
||||
|
||||
|
||||
def list_opts():
|
||||
return keystone.add_auth_options(_OPTS)
|
||||
return keystone.add_auth_options(_OPTS, SERVICE_TYPE)
|
||||
|
@ -49,16 +49,14 @@ from ironic_inspector.test.unit import test_rules
|
||||
|
||||
CONF = """
|
||||
[ironic]
|
||||
os_auth_url = http://url
|
||||
os_username = user
|
||||
os_password = password
|
||||
os_tenant_name = tenant
|
||||
auth_type=none
|
||||
endpoint_override=http://url
|
||||
[pxe_filter]
|
||||
driver = noop
|
||||
[DEFAULT]
|
||||
debug = True
|
||||
auth_strategy = noauth
|
||||
introspection_delay = 0
|
||||
auth_strategy=noauth
|
||||
[database]
|
||||
connection = sqlite:///%(db_file)s
|
||||
[processing]
|
||||
|
@ -27,6 +27,7 @@ from ironic_inspector import utils
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
@mock.patch.object(keystone, 'get_adapter')
|
||||
@mock.patch.object(keystone, 'register_auth_opts')
|
||||
@mock.patch.object(keystone, 'get_session')
|
||||
@mock.patch.object(client, 'Client')
|
||||
@ -39,35 +40,34 @@ class TestGetClient(base.BaseTest):
|
||||
self.addCleanup(ir_utils.reset_ironic_session)
|
||||
|
||||
def test_get_client_with_auth_token(self, mock_client, mock_load,
|
||||
mock_opts):
|
||||
mock_opts, mock_adapter):
|
||||
fake_token = 'token'
|
||||
fake_ironic_url = 'http://127.0.0.1:6385'
|
||||
mock_sess = mock.Mock()
|
||||
mock_sess.get_endpoint.return_value = fake_ironic_url
|
||||
mock_adapter.return_value.get_endpoint.return_value = fake_ironic_url
|
||||
mock_load.return_value = mock_sess
|
||||
ir_utils.get_client(fake_token)
|
||||
mock_sess.get_endpoint.assert_called_once_with(
|
||||
endpoint_type=CONF.ironic.os_endpoint_type,
|
||||
service_type=CONF.ironic.os_service_type,
|
||||
region_name=CONF.ironic.os_region)
|
||||
mock_adapter.assert_called_once_with(
|
||||
'ironic', region_name='somewhere', session=mock_sess)
|
||||
mock_adapter.return_value.get_endpoint.assert_called_once_with()
|
||||
args = {'token': fake_token,
|
||||
'endpoint': fake_ironic_url,
|
||||
'os_ironic_api_version': ir_utils.DEFAULT_IRONIC_API_VERSION,
|
||||
'max_retries': CONF.ironic.max_retries,
|
||||
'retry_interval': CONF.ironic.retry_interval}
|
||||
mock_client.assert_called_once_with(1, **args)
|
||||
mock_client.assert_called_once_with(1, fake_ironic_url, **args)
|
||||
|
||||
def test_get_client_without_auth_token(self, mock_client, mock_load,
|
||||
mock_opts):
|
||||
mock_opts, mock_adapter):
|
||||
fake_ironic_url = 'http://127.0.0.1:6385'
|
||||
mock_adapter.return_value.get_endpoint.return_value = fake_ironic_url
|
||||
mock_sess = mock.Mock()
|
||||
mock_load.return_value = mock_sess
|
||||
ir_utils.get_client(None)
|
||||
args = {'session': mock_sess,
|
||||
'region_name': 'somewhere',
|
||||
'os_ironic_api_version': ir_utils.DEFAULT_IRONIC_API_VERSION,
|
||||
'max_retries': CONF.ironic.max_retries,
|
||||
'retry_interval': CONF.ironic.retry_interval}
|
||||
mock_client.assert_called_once_with(1, **args)
|
||||
mock_client.assert_called_once_with(1, fake_ironic_url, **args)
|
||||
|
||||
|
||||
class TestGetIpmiAddress(base.BaseTest):
|
||||
|
@ -29,16 +29,18 @@ class KeystoneTest(base.BaseTest):
|
||||
self.cfg.conf.register_group(cfg.OptGroup(TESTGROUP))
|
||||
|
||||
def test_register_auth_opts(self):
|
||||
keystone.register_auth_opts(TESTGROUP)
|
||||
keystone.register_auth_opts(TESTGROUP, 'fake-service')
|
||||
auth_opts = ['auth_type', 'auth_section']
|
||||
sess_opts = ['certfile', 'keyfile', 'insecure', 'timeout', 'cafile']
|
||||
for o in auth_opts + sess_opts:
|
||||
self.assertIn(o, self.cfg.conf[TESTGROUP])
|
||||
self.assertEqual('password', self.cfg.conf[TESTGROUP]['auth_type'])
|
||||
self.assertEqual('fake-service',
|
||||
self.cfg.conf[TESTGROUP]['service_type'])
|
||||
|
||||
@mock.patch.object(kaloading, 'load_auth_from_conf_options', autospec=True)
|
||||
def test_get_session(self, auth_mock):
|
||||
keystone.register_auth_opts(TESTGROUP)
|
||||
keystone.register_auth_opts(TESTGROUP, 'fake-service')
|
||||
self.cfg.config(group=TESTGROUP,
|
||||
cafile='/path/to/ca/file')
|
||||
auth1 = mock.Mock()
|
||||
@ -48,7 +50,7 @@ class KeystoneTest(base.BaseTest):
|
||||
self.assertEqual(auth1, sess.auth)
|
||||
|
||||
def test_add_auth_options(self):
|
||||
opts = keystone.add_auth_options([])
|
||||
opts = keystone.add_auth_options([], 'fake-service')
|
||||
# check that there is no duplicates
|
||||
names = {o.dest for o in opts}
|
||||
self.assertEqual(len(names), len(opts))
|
||||
|
@ -166,6 +166,7 @@ class TestSetAttributeAction(test_base.NodeTest):
|
||||
'value': 42}])
|
||||
|
||||
|
||||
@mock.patch('ironic_inspector.common.ironic.get_client', new=mock.Mock())
|
||||
class TestSetCapabilityAction(test_base.NodeTest):
|
||||
act = rules_plugins.SetCapabilityAction()
|
||||
params = {'name': 'cap1', 'value': 'val'}
|
||||
@ -191,6 +192,7 @@ class TestSetCapabilityAction(test_base.NodeTest):
|
||||
self.assertEqual({'cap1': 'val', 'x': 'y', 'answer': '42'}, new_caps)
|
||||
|
||||
|
||||
@mock.patch('ironic_inspector.common.ironic.get_client', new=mock.Mock())
|
||||
class TestExtendAttributeAction(test_base.NodeTest):
|
||||
act = rules_plugins.ExtendAttributeAction()
|
||||
params = {'path': '/extra/value', 'value': 42}
|
||||
|
@ -26,6 +26,7 @@ from ironic_inspector import utils
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
@mock.patch('ironic_inspector.common.ironic.get_client', new=mock.Mock())
|
||||
class TestSchedulerHook(test_base.NodeTest):
|
||||
def setUp(self):
|
||||
super(TestSchedulerHook, self).setUp()
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
# Mostly copied from ironic/tests/test_swift.py
|
||||
|
||||
|
||||
from keystoneauth1 import loading as kloading
|
||||
import mock
|
||||
from swiftclient import client as swift_client
|
||||
from swiftclient import exceptions as swift_exception
|
||||
@ -44,6 +46,7 @@ class BaseTest(test_base.NodeTest):
|
||||
}
|
||||
|
||||
|
||||
@mock.patch.object(keystone, 'get_adapter', autospec=True)
|
||||
@mock.patch.object(keystone, 'register_auth_opts')
|
||||
@mock.patch.object(keystone, 'get_session')
|
||||
@mock.patch.object(swift_client, 'Connection', autospec=True)
|
||||
@ -58,14 +61,23 @@ class SwiftTestCase(BaseTest):
|
||||
os_endpoint_type='internalURL',
|
||||
os_region='somewhere',
|
||||
max_retries=2)
|
||||
# NOTE(aarefiev) register keystoneauth dynamic options
|
||||
adapter_opts = kloading.get_adapter_conf_options(
|
||||
include_deprecated=False)
|
||||
self.cfg.register_opts(adapter_opts, 'swift')
|
||||
self.addCleanup(swift.reset_swift_session)
|
||||
|
||||
def test___init__(self, connection_mock, load_mock, opts_mock):
|
||||
def test___init__(self, connection_mock, load_mock,
|
||||
opts_mock, adapter_mock):
|
||||
fake_endpoint = "http://localhost:6000"
|
||||
adapter_mock.return_value.get_endpoint.return_value = fake_endpoint
|
||||
swift.SwiftAPI()
|
||||
connection_mock.assert_called_once_with(
|
||||
session=load_mock.return_value)
|
||||
session=load_mock.return_value,
|
||||
os_options={'object_storage_url': fake_endpoint})
|
||||
|
||||
def test_create_object(self, connection_mock, load_mock, opts_mock):
|
||||
def test_create_object(self, connection_mock, load_mock,
|
||||
opts_mock, adapter_mock):
|
||||
swiftapi = swift.SwiftAPI()
|
||||
connection_obj_mock = connection_mock.return_value
|
||||
|
||||
@ -79,8 +91,8 @@ class SwiftTestCase(BaseTest):
|
||||
'ironic-inspector', 'object', 'some-string-data', headers=None)
|
||||
self.assertEqual('object-uuid', object_uuid)
|
||||
|
||||
def test_create_object_create_container_fails(self, connection_mock,
|
||||
load_mock, opts_mock):
|
||||
def test_create_object_create_container_fails(
|
||||
self, connection_mock, load_mock, opts_mock, adapter_mock):
|
||||
swiftapi = swift.SwiftAPI()
|
||||
connection_obj_mock = connection_mock.return_value
|
||||
connection_obj_mock.put_container.side_effect = self.swift_exception
|
||||
@ -91,7 +103,7 @@ class SwiftTestCase(BaseTest):
|
||||
self.assertFalse(connection_obj_mock.put_object.called)
|
||||
|
||||
def test_create_object_put_object_fails(self, connection_mock, load_mock,
|
||||
opts_mock):
|
||||
opts_mock, adapter_mock):
|
||||
swiftapi = swift.SwiftAPI()
|
||||
connection_obj_mock = connection_mock.return_value
|
||||
connection_obj_mock.put_object.side_effect = self.swift_exception
|
||||
@ -102,7 +114,8 @@ class SwiftTestCase(BaseTest):
|
||||
connection_obj_mock.put_object.assert_called_once_with(
|
||||
'ironic-inspector', 'object', 'some-string-data', headers=None)
|
||||
|
||||
def test_get_object(self, connection_mock, load_mock, opts_mock):
|
||||
def test_get_object(self, connection_mock, load_mock,
|
||||
opts_mock, adapter_mock):
|
||||
swiftapi = swift.SwiftAPI()
|
||||
connection_obj_mock = connection_mock.return_value
|
||||
|
||||
@ -115,7 +128,8 @@ class SwiftTestCase(BaseTest):
|
||||
'ironic-inspector', 'object')
|
||||
self.assertEqual(expected_obj, swift_obj)
|
||||
|
||||
def test_get_object_fails(self, connection_mock, load_mock, opts_mock):
|
||||
def test_get_object_fails(self, connection_mock, load_mock,
|
||||
opts_mock, adapter_mock):
|
||||
swiftapi = swift.SwiftAPI()
|
||||
connection_obj_mock = connection_mock.return_value
|
||||
connection_obj_mock.get_object.side_effect = self.swift_exception
|
||||
|
24
releasenotes/notes/ksadapters-abc9edc63cafa405.yaml
Normal file
24
releasenotes/notes/ksadapters-abc9edc63cafa405.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
deprecations:
|
||||
- |
|
||||
Several configuration options related to ironic API access
|
||||
are deprecated and will be removed in the Rocky release.
|
||||
These include:
|
||||
|
||||
- ``[ironic]/os_region`` - use ``[ironic]/region_name`` option instead
|
||||
- ``[ironic]/auth_strategy`` - set ``[ironic]/auth_type`` option to
|
||||
``none`` to access ironic API in noauth mode
|
||||
- ``[ironic]/ironic_url`` - use ``[ironic]/endpoint_override`` option
|
||||
to set specific ironic API endpoint address if discovery of ironic API
|
||||
endpoint is not desired or impossible (for example in standalone mode)
|
||||
- ``[ironic]/os_service_type`` - use ``[ironic]/service_type`` option
|
||||
- ``[ironic]/os_endpoint_type`` - use ``[ironic]/valid_interfaces``
|
||||
option to set ironic endpoint types that will be attempted to be used
|
||||
- |
|
||||
Several configuration options related to swift API access are deprecated
|
||||
and will be removed in Rocky release.
|
||||
These include:
|
||||
|
||||
- ``[swift]/os_service_type`` - use ``[swift]/service_type`` option
|
||||
- ``[swift]/os_endpoint_type`` - use ``[swift]/valid_interfaces`` option
|
||||
- ``[swift]/os_region`` - use ``[swift]region_name`` option
|
Loading…
Reference in New Issue
Block a user