diff --git a/config-generator.conf b/config-generator.conf index b3c8f42b2..fae4268a6 100644 --- a/config-generator.conf +++ b/config-generator.conf @@ -1,11 +1,6 @@ [DEFAULT] output_file = example.conf namespace = ironic_inspector -namespace = ironic_inspector.common.ironic -namespace = ironic_inspector.common.swift -namespace = ironic_inspector.plugins.capabilities -namespace = ironic_inspector.plugins.discovery -namespace = ironic_inspector.plugins.pci_devices namespace = keystonemiddleware.auth_token namespace = oslo.db namespace = oslo.log diff --git a/example.conf b/example.conf index 92bfef706..0b341f22f 100644 --- a/example.conf +++ b/example.conf @@ -183,7 +183,7 @@ [capabilities] # -# From ironic_inspector.plugins.capabilities +# From ironic_inspector # # Whether to store the boot mode (BIOS or UEFI). (boolean value) @@ -340,7 +340,7 @@ [discovery] # -# From ironic_inspector.plugins.discovery +# From ironic_inspector # # The name of the Ironic driver used by the enroll hook when creating @@ -408,7 +408,7 @@ [ironic] # -# From ironic_inspector.common.ironic +# From ironic_inspector # # Authentication URL (string value) @@ -763,7 +763,7 @@ [pci_devices] # -# From ironic_inspector.plugins.pci_devices +# From ironic_inspector # # An alias for PCI device identified by 'vendor_id' and 'product_id' @@ -868,7 +868,7 @@ [swift] # -# From ironic_inspector.common.swift +# From ironic_inspector # # Authentication URL (string value) diff --git a/ironic_inspector/common/ironic.py b/ironic_inspector/common/ironic.py index f61cf6e4f..7541453fe 100644 --- a/ironic_inspector/common/ironic.py +++ b/ironic_inspector/common/ironic.py @@ -31,41 +31,6 @@ VALID_STATES = {'enroll', 'manageable', 'inspecting', 'inspect failed'} # 1.19 is API version, which supports port.pxe_enabled DEFAULT_IRONIC_API_VERSION = '1.19' -IRONIC_GROUP = 'ironic' - -IRONIC_OPTS = [ - cfg.StrOpt('os_region', - help=_('Keystone region used to get Ironic endpoints.')), - cfg.StrOpt('auth_strategy', - default='keystone', - choices=('keystone', 'noauth'), - help=_('Method to use for authentication: noauth or ' - 'keystone.')), - 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.')), - cfg.StrOpt('os_service_type', - default='baremetal', - help=_('Ironic service type.')), - cfg.StrOpt('os_endpoint_type', - default='internalURL', - help=_('Ironic endpoint type.')), - cfg.IntOpt('retry_interval', - default=2, - help=_('Interval between retries in case of conflict error ' - '(HTTP 409).')), - cfg.IntOpt('max_retries', - default=30, - help=_('Maximum number of retries in case of conflict error ' - '(HTTP 409).')), -] - - -CONF.register_opts(IRONIC_OPTS, group=IRONIC_GROUP) -keystone.register_auth_opts(IRONIC_GROUP) - IRONIC_SESSION = None @@ -124,7 +89,7 @@ def get_client(token=None, else: global IRONIC_SESSION if not IRONIC_SESSION: - IRONIC_SESSION = keystone.get_session(IRONIC_GROUP) + IRONIC_SESSION = keystone.get_session('ironic') if token is None: args = {'session': IRONIC_SESSION, 'region_name': CONF.ironic.os_region} @@ -182,7 +147,3 @@ def get_node(node_id, ironic=None, **kwargs): except ironic_exc.HttpError as exc: raise utils.Error(_("Cannot get node %(node)s: %(exc)s") % {'node': node_id, 'exc': exc}) - - -def list_opts(): - return keystone.add_auth_options(IRONIC_OPTS, IRONIC_GROUP) diff --git a/ironic_inspector/common/keystone.py b/ironic_inspector/common/keystone.py index 28bf6290f..52dc6afc9 100644 --- a/ironic_inspector/common/keystone.py +++ b/ironic_inspector/common/keystone.py @@ -33,7 +33,7 @@ def get_session(group): return session -def add_auth_options(options, group): +def add_auth_options(options): def add_options(opts, opts_to_add): for new_opt in opts_to_add: @@ -53,4 +53,4 @@ def add_auth_options(options, group): add_options(opts, loading.get_auth_plugin_conf_options(plugin)) add_options(opts, loading.get_session_conf_options()) opts.sort(key=lambda x: x.name) - return [(group, opts)] + return opts diff --git a/ironic_inspector/common/service_utils.py b/ironic_inspector/common/service_utils.py index b690c1a3b..ba09428b9 100644 --- a/ironic_inspector/common/service_utils.py +++ b/ironic_inspector/common/service_utils.py @@ -10,19 +10,20 @@ # License for the specific language governing permissions and limitations # under the License. +from oslo_config import cfg from oslo_log import log -from ironic_inspector import conf +from ironic_inspector.conf import opts LOG = log.getLogger(__name__) -CONF = conf.cfg.CONF +CONF = cfg.CONF def prepare_service(args=None): args = [] if args is None else args log.register_options(CONF) - conf.set_config_defaults() - conf.parse_args(args) + opts.set_config_defaults() + opts.parse_args(args) log.setup(CONF, 'ironic_inspector') LOG.debug("Configuration:") diff --git a/ironic_inspector/common/swift.py b/ironic_inspector/common/swift.py index 547a2d22d..5bf2c8d1b 100644 --- a/ironic_inspector/common/swift.py +++ b/ironic_inspector/common/swift.py @@ -26,34 +26,6 @@ from ironic_inspector import utils CONF = cfg.CONF -SWIFT_GROUP = 'swift' -SWIFT_OPTS = [ - cfg.IntOpt('max_retries', - default=2, - help=_('Maximum number of times to retry a Swift request, ' - 'before failing.')), - cfg.IntOpt('delete_after', - default=0, - help=_('Number of seconds that the Swift object will last ' - 'before being deleted. (set to 0 to never delete the ' - 'object).')), - cfg.StrOpt('container', - default='ironic-inspector', - help=_('Default Swift container to use when creating ' - 'objects.')), - cfg.StrOpt('os_service_type', - default='object-store', - help=_('Swift service type.')), - cfg.StrOpt('os_endpoint_type', - default='internalURL', - help=_('Swift endpoint type.')), - cfg.StrOpt('os_region', - help=_('Keystone region to get endpoint for.')), -] - -CONF.register_opts(SWIFT_OPTS, group=SWIFT_GROUP) -keystone.register_auth_opts(SWIFT_GROUP) - OBJECT_NAME_PREFIX = 'inspector_data' SWIFT_SESSION = None @@ -77,7 +49,7 @@ class SwiftAPI(object): """ global SWIFT_SESSION if not SWIFT_SESSION: - SWIFT_SESSION = keystone.get_session(SWIFT_GROUP) + SWIFT_SESSION = keystone.get_session('swift') self.connection = swift_client.Connection(session=SWIFT_SESSION) @@ -166,7 +138,3 @@ def get_introspection_data(uuid, suffix=None): if suffix is not None: swift_object_name = '%s-%s' % (swift_object_name, suffix) return swift_api.get_object(swift_object_name) - - -def list_opts(): - return keystone.add_auth_options(SWIFT_OPTS, SWIFT_GROUP) diff --git a/ironic_inspector/conf.py b/ironic_inspector/conf.py deleted file mode 100644 index b8c724578..000000000 --- a/ironic_inspector/conf.py +++ /dev/null @@ -1,283 +0,0 @@ -# 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 -from oslo_log import log -from oslo_middleware import cors - -from ironic_inspector.common.i18n import _ -from ironic_inspector import version - - -MIN_VERSION_HEADER = 'X-OpenStack-Ironic-Inspector-API-Minimum-Version' -MAX_VERSION_HEADER = 'X-OpenStack-Ironic-Inspector-API-Maximum-Version' -VERSION_HEADER = 'X-OpenStack-Ironic-Inspector-API-Version' - -VALID_ADD_PORTS_VALUES = ('all', 'active', 'pxe', 'disabled') -VALID_KEEP_PORTS_VALUES = ('all', 'present', 'added') -VALID_STORE_DATA_VALUES = ('none', 'swift') - - -IPTABLES_OPTS = [ - cfg.BoolOpt('manage_firewall', - default=True, - # NOTE(milan) this filter driver will be replaced by - # a dnsmasq filter driver - deprecated_for_removal=True, - deprecated_group='firewall', - help=_('Whether to manage firewall rules for PXE port. ' - 'This configuration option was deprecated in favor of ' - 'the ``driver`` option in the ``pxe_filter`` section. ' - 'Please, use the ``noop`` filter driver to disable the ' - 'firewall filtering or the ``iptables`` filter driver ' - 'to enable it.')), - cfg.StrOpt('dnsmasq_interface', - default='br-ctlplane', - deprecated_group='firewall', - help=_('Interface on which dnsmasq listens, the default is for ' - 'VM\'s.')), - cfg.StrOpt('firewall_chain', - default='ironic-inspector', - deprecated_group='firewall', - help=_('iptables chain name to use.')), - cfg.ListOpt('ethoib_interfaces', - deprecated_group='firewall', - default=[], - help=_('List of Etherent Over InfiniBand interfaces ' - 'on the Inspector host which are used for physical ' - 'access to the DHCP network. Multiple interfaces would ' - 'be attached to a bond or bridge specified in ' - 'dnsmasq_interface. The MACs of the InfiniBand nodes ' - 'which are not in desired state are going to be ' - 'blacklisted based on the list of neighbor MACs ' - 'on these interfaces.')), -] - -PROCESSING_OPTS = [ - cfg.StrOpt('add_ports', - default='pxe', - help=_('Which MAC addresses to add as ports during ' - 'introspection. Possible values: all ' - '(all MAC addresses), active (MAC addresses of NIC with ' - '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).'), - choices=VALID_ADD_PORTS_VALUES), - cfg.StrOpt('keep_ports', - default='all', - help=_('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).'), - choices=VALID_KEEP_PORTS_VALUES), - cfg.BoolOpt('overwrite_existing', - default=True, - help=_('Whether to overwrite existing values in node ' - 'database. Disable this option to make ' - 'introspection a non-destructive operation.')), - cfg.StrOpt('default_processing_hooks', - default='ramdisk_error,root_disk_selection,scheduler,' - 'validate_interfaces,capabilities,pci_devices', - help=_('Comma-separated list of default hooks for processing ' - 'pipeline. Hook \'scheduler\' updates the node with the ' - 'minimum properties required by the Nova scheduler. ' - 'Hook \'validate_interfaces\' ensures that valid NIC ' - 'data was provided by the ramdisk. ' - 'Do not exclude these two unless you really know what ' - 'you\'re doing.')), - cfg.StrOpt('processing_hooks', - default='$default_processing_hooks', - help=_('Comma-separated list of enabled hooks for processing ' - 'pipeline. The default for this is ' - '$default_processing_hooks, hooks can be added before ' - 'or after the defaults like this: ' - '"prehook,$default_processing_hooks,posthook".')), - cfg.StrOpt('ramdisk_logs_dir', - help=_('If set, logs from ramdisk will be stored in this ' - 'directory.')), - cfg.BoolOpt('always_store_ramdisk_logs', - default=False, - help=_('Whether to store ramdisk logs even if it did not ' - 'return an error message (dependent upon ' - '"ramdisk_logs_dir" option being set).')), - cfg.StrOpt('node_not_found_hook', - help=_('The name of the hook to run when inspector receives ' - 'inspection information from a node it isn\'t already ' - 'aware of. This hook is ignored by default.')), - cfg.StrOpt('store_data', - default='none', - choices=VALID_STORE_DATA_VALUES, - help=_('Method for storing introspection data. If set to \'none' - '\', introspection data will not be stored.')), - cfg.StrOpt('store_data_location', - help=_('Name of the key to store the location of stored data ' - 'in the extra column of the Ironic database.')), - cfg.BoolOpt('disk_partitioning_spacing', - default=True, - help=_('Whether to leave 1 GiB of disk size untouched for ' - 'partitioning. Only has effect when used with the IPA ' - 'as a ramdisk, for older ramdisk local_gb is ' - 'calculated on the ramdisk side.')), - cfg.StrOpt('ramdisk_logs_filename_format', - default='{uuid}_{dt:%Y%m%d-%H%M%S.%f}.tar.gz', - help=_('File name template for storing ramdisk logs. The ' - 'following replacements can be used: ' - '{uuid} - node UUID or "unknown", ' - '{bmc} - node BMC address or "unknown", ' - '{dt} - current UTC date and time, ' - '{mac} - PXE booting MAC or "unknown".')), - cfg.BoolOpt('power_off', - default=True, - help=_('Whether to power off a node after introspection.')), -] - -SERVICE_OPTS = [ - cfg.StrOpt('listen_address', - default='0.0.0.0', - help=_('IP to listen on.')), - cfg.PortOpt('listen_port', - default=5050, - help=_('Port to listen on.')), - cfg.StrOpt('auth_strategy', - default='keystone', - choices=('keystone', 'noauth'), - help=_('Authentication method used on the ironic-inspector ' - 'API. Either "noauth" or "keystone" are currently valid ' - 'options. "noauth" will disable all authentication.')), - cfg.IntOpt('timeout', - default=3600, - help=_('Timeout after which introspection is considered ' - 'failed, set to 0 to disable.')), - cfg.IntOpt('node_status_keep_time', - default=0, - help=_('For how much time (in seconds) to keep status ' - 'information about nodes after introspection was ' - 'finished for them. Set to 0 (the default) ' - 'to disable the timeout.'), - deprecated_for_removal=True), - cfg.IntOpt('clean_up_period', - default=60, - help=_('Amount of time in seconds, after which repeat clean up ' - 'of timed out nodes and old nodes status information.')), - cfg.BoolOpt('use_ssl', - default=False, - help=_('SSL Enabled/Disabled')), - cfg.StrOpt('ssl_cert_path', - default='', - help=_('Path to SSL certificate')), - cfg.StrOpt('ssl_key_path', - default='', - help=_('Path to SSL key')), - cfg.IntOpt('max_concurrency', - default=1000, min=2, - help=_('The green thread pool size.')), - cfg.IntOpt('introspection_delay', - default=5, - help=_('Delay (in seconds) between two introspections.')), - cfg.ListOpt('ipmi_address_fields', - default=['ilo_address', 'drac_host', 'drac_address', - 'cimc_address'], - help=_('Ironic driver_info fields that are equivalent ' - 'to ipmi_address.')), - cfg.StrOpt('rootwrap_config', - default="/etc/ironic-inspector/rootwrap.conf", - help=_('Path to the rootwrap configuration file to use for ' - 'running commands as root')), - cfg.IntOpt('api_max_limit', default=1000, min=1, - help=_('Limit the number of elements an API list-call returns')) -] - - -PXE_FILTER_OPTS = [ - cfg.StrOpt('driver', default='iptables', - help=_('PXE boot filter driver to use, such as iptables')), - cfg.IntOpt('sync_period', default=15, min=0, - deprecated_name='firewall_update_period', - deprecated_group='firewall', - help=_('Amount of time in seconds, after which repeat periodic ' - 'update of the filter.')), -] - -DNSMASQ_PXE_FILTER_OPTS = [ - cfg.StrOpt('dhcp_hostsdir', - default='/var/lib/ironic-inspector/dhcp-hostsdir', - help=_('The MAC address cache directory, exposed to dnsmasq.' - 'This directory is expected to be in exclusive control ' - 'of the driver.')), - cfg.BoolOpt('purge_dhcp_hostsdir', default=True, - help=_('Purge the hostsdir upon driver initialization. ' - 'Setting to false should only be performed when the ' - 'deployment of inspector is such that there are ' - 'multiple processes executing inside of the same host ' - 'and namespace. In this case, the Operator is ' - 'responsible for setting up a custom cleaning ' - 'facility.')), - cfg.StrOpt('dnsmasq_start_command', default='', - help=_('A (shell) command line to start the dnsmasq service ' - 'upon filter initialization. Default: don\'t start.')), - cfg.StrOpt('dnsmasq_stop_command', default='', - help=_('A (shell) command line to stop the dnsmasq service ' - 'upon inspector (error) exit. Default: don\'t stop.')), -] - - -cfg.CONF.register_opts(SERVICE_OPTS) -cfg.CONF.register_opts(IPTABLES_OPTS, group='iptables') -cfg.CONF.register_opts(PROCESSING_OPTS, group='processing') -cfg.CONF.register_opts(PXE_FILTER_OPTS, 'pxe_filter') -cfg.CONF.register_opts(DNSMASQ_PXE_FILTER_OPTS, group='dnsmasq_pxe_filter') - - -def list_opts(): - return [ - ('', SERVICE_OPTS), - ('iptables', IPTABLES_OPTS), - ('processing', PROCESSING_OPTS), - ('pxe_filter', PXE_FILTER_OPTS), - ('dnsmasq_pxe_filter', DNSMASQ_PXE_FILTER_OPTS), - ] - - -def set_config_defaults(): - """This method updates all configuration default values.""" - log.set_defaults(default_log_levels=['sqlalchemy=WARNING', - 'iso8601=WARNING', - 'requests=WARNING', - 'urllib3.connectionpool=WARNING', - 'keystonemiddleware=WARNING', - 'swiftclient=WARNING', - 'keystoneauth=WARNING', - 'ironicclient=WARNING']) - set_cors_middleware_defaults() - - -def set_cors_middleware_defaults(): - """Update default configuration options for oslo.middleware.""" - # TODO(krotscheck): Update with https://review.openstack.org/#/c/285368/ - cfg.set_defaults( - cors.CORS_OPTS, - allow_headers=['X-Auth-Token', - MIN_VERSION_HEADER, - MAX_VERSION_HEADER, - VERSION_HEADER], - allow_methods=['GET', 'POST', 'PUT', 'HEAD', - 'PATCH', 'DELETE', 'OPTIONS'] - ) - - -def parse_args(args, default_config_files=None): - cfg.CONF(args, - project='ironic-inspector', - version=version.version_info.release_string(), - default_config_files=default_config_files) diff --git a/ironic_inspector/conf/__init__.py b/ironic_inspector/conf/__init__.py new file mode 100644 index 000000000..e1720cd35 --- /dev/null +++ b/ironic_inspector/conf/__init__.py @@ -0,0 +1,39 @@ +# 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 + +from oslo_config import cfg + +from ironic_inspector.conf import capabilities +from ironic_inspector.conf import default +from ironic_inspector.conf import discovery +from ironic_inspector.conf import dnsmasq_pxe_filter +from ironic_inspector.conf import iptables +from ironic_inspector.conf import ironic +from ironic_inspector.conf import pci_devices +from ironic_inspector.conf import processing +from ironic_inspector.conf import pxe_filter +from ironic_inspector.conf import swift + + +CONF = cfg.CONF + + +capabilities.register_opts(CONF) +discovery.register_opts(CONF) +default.register_opts(CONF) +dnsmasq_pxe_filter.register_opts(CONF) +iptables.register_opts(CONF) +ironic.register_opts(CONF) +pci_devices.register_opts(CONF) +processing.register_opts(CONF) +pxe_filter.register_opts(CONF) +swift.register_opts(CONF) diff --git a/ironic_inspector/conf/capabilities.py b/ironic_inspector/conf/capabilities.py new file mode 100644 index 000000000..82ac85fc3 --- /dev/null +++ b/ironic_inspector/conf/capabilities.py @@ -0,0 +1,45 @@ +# 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 + +from ironic_inspector.common.i18n import _ + + +DEFAULT_CPU_FLAGS_MAPPING = { + 'vmx': 'cpu_vt', + 'svm': 'cpu_vt', + 'aes': 'cpu_aes', + 'pse': 'cpu_hugepages', + 'pdpe1gb': 'cpu_hugepages_1g', + 'smx': 'cpu_txt', +} + + +_OPTS = [ + cfg.BoolOpt('boot_mode', + default=False, + help=_('Whether to store the boot mode (BIOS or UEFI).')), + cfg.DictOpt('cpu_flags', + default=DEFAULT_CPU_FLAGS_MAPPING, + help=_('Mapping between a CPU flag and a capability to set ' + 'if this flag is present.')), +] + + +def register_opts(conf): + conf.register_opts(_OPTS, 'capabilities') + + +def list_opts(): + return _OPTS diff --git a/ironic_inspector/conf/default.py b/ironic_inspector/conf/default.py new file mode 100644 index 000000000..a9efc6b5d --- /dev/null +++ b/ironic_inspector/conf/default.py @@ -0,0 +1,81 @@ +# 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 + +from ironic_inspector.common.i18n import _ + + +_OPTS = [ + cfg.StrOpt('listen_address', + default='0.0.0.0', + help=_('IP to listen on.')), + cfg.PortOpt('listen_port', + default=5050, + help=_('Port to listen on.')), + cfg.StrOpt('auth_strategy', + default='keystone', + choices=('keystone', 'noauth'), + help=_('Authentication method used on the ironic-inspector ' + 'API. Either "noauth" or "keystone" are currently valid ' + 'options. "noauth" will disable all authentication.')), + cfg.IntOpt('timeout', + default=3600, + help=_('Timeout after which introspection is considered ' + 'failed, set to 0 to disable.')), + cfg.IntOpt('node_status_keep_time', + default=0, + help=_('For how much time (in seconds) to keep status ' + 'information about nodes after introspection was ' + 'finished for them. Set to 0 (the default) ' + 'to disable the timeout.'), + deprecated_for_removal=True), + cfg.IntOpt('clean_up_period', + default=60, + help=_('Amount of time in seconds, after which repeat clean up ' + 'of timed out nodes and old nodes status information.')), + cfg.BoolOpt('use_ssl', + default=False, + help=_('SSL Enabled/Disabled')), + cfg.StrOpt('ssl_cert_path', + default='', + help=_('Path to SSL certificate')), + cfg.StrOpt('ssl_key_path', + default='', + help=_('Path to SSL key')), + cfg.IntOpt('max_concurrency', + default=1000, min=2, + help=_('The green thread pool size.')), + cfg.IntOpt('introspection_delay', + default=5, + help=_('Delay (in seconds) between two introspections.')), + cfg.ListOpt('ipmi_address_fields', + default=['ilo_address', 'drac_host', 'drac_address', + 'cimc_address'], + help=_('Ironic driver_info fields that are equivalent ' + 'to ipmi_address.')), + cfg.StrOpt('rootwrap_config', + default="/etc/ironic-inspector/rootwrap.conf", + help=_('Path to the rootwrap configuration file to use for ' + 'running commands as root')), + cfg.IntOpt('api_max_limit', default=1000, min=1, + help=_('Limit the number of elements an API list-call returns')) +] + + +def register_opts(conf): + conf.register_opts(_OPTS) + + +def list_opts(): + return _OPTS diff --git a/ironic_inspector/conf/discovery.py b/ironic_inspector/conf/discovery.py new file mode 100644 index 000000000..296caa002 --- /dev/null +++ b/ironic_inspector/conf/discovery.py @@ -0,0 +1,32 @@ +# 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 + +from ironic_inspector.common.i18n import _ + + +_OPTS = [ + cfg.StrOpt('enroll_node_driver', + default='fake', + help=_('The name of the Ironic driver used by the enroll ' + 'hook when creating a new node in Ironic.')), +] + + +def register_opts(conf): + conf.register_opts(_OPTS, 'discovery') + + +def list_opts(): + return _OPTS diff --git a/ironic_inspector/conf/dnsmasq_pxe_filter.py b/ironic_inspector/conf/dnsmasq_pxe_filter.py new file mode 100644 index 000000000..53b83890a --- /dev/null +++ b/ironic_inspector/conf/dnsmasq_pxe_filter.py @@ -0,0 +1,48 @@ +# 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 + +from ironic_inspector.common.i18n import _ + + +_OPTS = [ + cfg.StrOpt('dhcp_hostsdir', + default='/var/lib/ironic-inspector/dhcp-hostsdir', + help=_('The MAC address cache directory, exposed to dnsmasq.' + 'This directory is expected to be in exclusive control ' + 'of the driver.')), + cfg.BoolOpt('purge_dhcp_hostsdir', default=True, + help=_('Purge the hostsdir upon driver initialization. ' + 'Setting to false should only be performed when the ' + 'deployment of inspector is such that there are ' + 'multiple processes executing inside of the same host ' + 'and namespace. In this case, the Operator is ' + 'responsible for setting up a custom cleaning ' + 'facility.')), + cfg.StrOpt('dnsmasq_start_command', default='', + help=_('A (shell) command line to start the dnsmasq service ' + 'upon filter initialization. Default: don\'t start.')), + cfg.StrOpt('dnsmasq_stop_command', default='', + help=_('A (shell) command line to stop the dnsmasq service ' + 'upon inspector (error) exit. Default: don\'t stop.')), + +] + + +def register_opts(conf): + conf.register_opts(_OPTS, 'dnsmasq_pxe_filter') + + +def list_opts(): + return _OPTS diff --git a/ironic_inspector/conf/iptables.py b/ironic_inspector/conf/iptables.py new file mode 100644 index 000000000..ea0e0859d --- /dev/null +++ b/ironic_inspector/conf/iptables.py @@ -0,0 +1,60 @@ +# 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 + +from ironic_inspector.common.i18n import _ + + +_OPTS = [ + cfg.BoolOpt('manage_firewall', + default=True, + # NOTE(milan) this filter driver will be replaced by + # a dnsmasq filter driver + deprecated_for_removal=True, + deprecated_group='firewall', + help=_('Whether to manage firewall rules for PXE port. ' + 'This configuration option was deprecated in favor of ' + 'the ``driver`` option in the ``pxe_filter`` section. ' + 'Please, use the ``noop`` filter driver to disable the ' + 'firewall filtering or the ``iptables`` filter driver ' + 'to enable it.')), + cfg.StrOpt('dnsmasq_interface', + default='br-ctlplane', + deprecated_group='firewall', + help=_('Interface on which dnsmasq listens, the default is for ' + 'VM\'s.')), + cfg.StrOpt('firewall_chain', + default='ironic-inspector', + deprecated_group='firewall', + help=_('iptables chain name to use.')), + cfg.ListOpt('ethoib_interfaces', + deprecated_group='firewall', + default=[], + help=_('List of Etherent Over InfiniBand interfaces ' + 'on the Inspector host which are used for physical ' + 'access to the DHCP network. Multiple interfaces would ' + 'be attached to a bond or bridge specified in ' + 'dnsmasq_interface. The MACs of the InfiniBand nodes ' + 'which are not in desired state are going to be ' + 'blacklisted based on the list of neighbor MACs ' + 'on these interfaces.')), +] + + +def register_opts(conf): + conf.register_opts(_OPTS, 'iptables') + + +def list_opts(): + return _OPTS diff --git a/ironic_inspector/conf/ironic.py b/ironic_inspector/conf/ironic.py new file mode 100644 index 000000000..ea26371cc --- /dev/null +++ b/ironic_inspector/conf/ironic.py @@ -0,0 +1,59 @@ +# 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 + +from ironic_inspector.common.i18n import _ +from ironic_inspector.common import keystone + + +IRONIC_GROUP = 'ironic' + + +_OPTS = [ + cfg.StrOpt('os_region', + help=_('Keystone region used to get Ironic endpoints.')), + cfg.StrOpt('auth_strategy', + default='keystone', + choices=('keystone', 'noauth'), + help=_('Method to use for authentication: noauth or ' + 'keystone.')), + 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.')), + cfg.StrOpt('os_service_type', + default='baremetal', + help=_('Ironic service type.')), + cfg.StrOpt('os_endpoint_type', + default='internalURL', + help=_('Ironic endpoint type.')), + cfg.IntOpt('retry_interval', + default=2, + help=_('Interval between retries in case of conflict error ' + '(HTTP 409).')), + cfg.IntOpt('max_retries', + default=30, + help=_('Maximum number of retries in case of conflict error ' + '(HTTP 409).')), +] + + +def register_opts(conf): + conf.register_opts(_OPTS, IRONIC_GROUP) + keystone.register_auth_opts(IRONIC_GROUP) + + +def list_opts(): + return keystone.add_auth_options(_OPTS) diff --git a/ironic_inspector/conf/opts.py b/ironic_inspector/conf/opts.py new file mode 100644 index 000000000..d480f1a33 --- /dev/null +++ b/ironic_inspector/conf/opts.py @@ -0,0 +1,74 @@ +# 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 +from oslo_log import log +from oslo_middleware import cors + +import ironic_inspector.conf +from ironic_inspector import version + + +MIN_VERSION_HEADER = 'X-OpenStack-Ironic-Inspector-API-Minimum-Version' +MAX_VERSION_HEADER = 'X-OpenStack-Ironic-Inspector-API-Maximum-Version' +VERSION_HEADER = 'X-OpenStack-Ironic-Inspector-API-Version' + + +def set_config_defaults(): + """Return a list of oslo.config options available in Inspector code.""" + log.set_defaults(default_log_levels=['sqlalchemy=WARNING', + 'iso8601=WARNING', + 'requests=WARNING', + 'urllib3.connectionpool=WARNING', + 'keystonemiddleware=WARNING', + 'swiftclient=WARNING', + 'keystoneauth=WARNING', + 'ironicclient=WARNING']) + set_cors_middleware_defaults() + + +def set_cors_middleware_defaults(): + """Update default configuration options for oslo.middleware.""" + # TODO(krotscheck): Update with https://review.openstack.org/#/c/285368/ + cfg.set_defaults( + cors.CORS_OPTS, + allow_headers=['X-Auth-Token', + MIN_VERSION_HEADER, + MAX_VERSION_HEADER, + VERSION_HEADER], + allow_methods=['GET', 'POST', 'PUT', 'HEAD', + 'PATCH', 'DELETE', 'OPTIONS'] + ) + + +def parse_args(args, default_config_files=None): + cfg.CONF(args, + project='ironic-inspector', + version=version.version_info.release_string(), + default_config_files=default_config_files) + + +def list_opts(): + return [ + ('capabilities', ironic_inspector.conf.capabilities.list_opts()), + ('DEFAULT', ironic_inspector.conf.default.list_opts()), + ('discovery', ironic_inspector.conf.discovery.list_opts()), + ('dnsmasq_pxe_filter', + ironic_inspector.conf.dnsmasq_pxe_filter.list_opts()), + ('swift', ironic_inspector.conf.swift.list_opts()), + ('ironic', ironic_inspector.conf.ironic.list_opts()), + ('iptables', ironic_inspector.conf.iptables.list_opts()), + ('processing', ironic_inspector.conf.processing.list_opts()), + ('pci_devices', ironic_inspector.conf.pci_devices.list_opts()), + ('pxe_filter', ironic_inspector.conf.pxe_filter.list_opts()), + ] diff --git a/ironic_inspector/conf/pci_devices.py b/ironic_inspector/conf/pci_devices.py new file mode 100644 index 000000000..2951d41a5 --- /dev/null +++ b/ironic_inspector/conf/pci_devices.py @@ -0,0 +1,34 @@ +# 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 + +from ironic_inspector.common.i18n import _ + + +_OPTS = [ + cfg.MultiStrOpt('alias', + default=[], + help=_('An alias for PCI device identified by ' + '\'vendor_id\' and \'product_id\' fields. Format: ' + '{"vendor_id": "1234", "product_id": "5678", ' + '"name": "pci_dev1"}')), +] + + +def register_opts(conf): + conf.register_opts(_OPTS, group='pci_devices') + + +def list_opts(): + return _OPTS diff --git a/ironic_inspector/conf/processing.py b/ironic_inspector/conf/processing.py new file mode 100644 index 000000000..9840f47cd --- /dev/null +++ b/ironic_inspector/conf/processing.py @@ -0,0 +1,109 @@ +# 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 + +from ironic_inspector.common.i18n import _ + + +VALID_ADD_PORTS_VALUES = ('all', 'active', 'pxe', 'disabled') +VALID_KEEP_PORTS_VALUES = ('all', 'present', 'added') +VALID_STORE_DATA_VALUES = ('none', 'swift') + + +_OPTS = [ + cfg.StrOpt('add_ports', + default='pxe', + help=_('Which MAC addresses to add as ports during ' + 'introspection. Possible values: all ' + '(all MAC addresses), active (MAC addresses of NIC with ' + '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).'), + choices=VALID_ADD_PORTS_VALUES), + cfg.StrOpt('keep_ports', + default='all', + help=_('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).'), + choices=VALID_KEEP_PORTS_VALUES), + cfg.BoolOpt('overwrite_existing', + default=True, + help=_('Whether to overwrite existing values in node ' + 'database. Disable this option to make ' + 'introspection a non-destructive operation.')), + cfg.StrOpt('default_processing_hooks', + default='ramdisk_error,root_disk_selection,scheduler,' + 'validate_interfaces,capabilities,pci_devices', + help=_('Comma-separated list of default hooks for processing ' + 'pipeline. Hook \'scheduler\' updates the node with the ' + 'minimum properties required by the Nova scheduler. ' + 'Hook \'validate_interfaces\' ensures that valid NIC ' + 'data was provided by the ramdisk. ' + 'Do not exclude these two unless you really know what ' + 'you\'re doing.')), + cfg.StrOpt('processing_hooks', + default='$default_processing_hooks', + help=_('Comma-separated list of enabled hooks for processing ' + 'pipeline. The default for this is ' + '$default_processing_hooks, hooks can be added before ' + 'or after the defaults like this: ' + '"prehook,$default_processing_hooks,posthook".')), + cfg.StrOpt('ramdisk_logs_dir', + help=_('If set, logs from ramdisk will be stored in this ' + 'directory.')), + cfg.BoolOpt('always_store_ramdisk_logs', + default=False, + help=_('Whether to store ramdisk logs even if it did not ' + 'return an error message (dependent upon ' + '"ramdisk_logs_dir" option being set).')), + cfg.StrOpt('node_not_found_hook', + help=_('The name of the hook to run when inspector receives ' + 'inspection information from a node it isn\'t already ' + 'aware of. This hook is ignored by default.')), + cfg.StrOpt('store_data', + default='none', + choices=VALID_STORE_DATA_VALUES, + help=_('Method for storing introspection data. If set to \'none' + '\', introspection data will not be stored.')), + cfg.StrOpt('store_data_location', + help=_('Name of the key to store the location of stored data ' + 'in the extra column of the Ironic database.')), + cfg.BoolOpt('disk_partitioning_spacing', + default=True, + help=_('Whether to leave 1 GiB of disk size untouched for ' + 'partitioning. Only has effect when used with the IPA ' + 'as a ramdisk, for older ramdisk local_gb is ' + 'calculated on the ramdisk side.')), + cfg.StrOpt('ramdisk_logs_filename_format', + default='{uuid}_{dt:%Y%m%d-%H%M%S.%f}.tar.gz', + help=_('File name template for storing ramdisk logs. The ' + 'following replacements can be used: ' + '{uuid} - node UUID or "unknown", ' + '{bmc} - node BMC address or "unknown", ' + '{dt} - current UTC date and time, ' + '{mac} - PXE booting MAC or "unknown".')), + cfg.BoolOpt('power_off', + default=True, + help=_('Whether to power off a node after introspection.')), +] + + +def register_opts(conf): + conf.register_opts(_OPTS, 'processing') + + +def list_opts(): + return _OPTS diff --git a/ironic_inspector/conf/pxe_filter.py b/ironic_inspector/conf/pxe_filter.py new file mode 100644 index 000000000..b095720a5 --- /dev/null +++ b/ironic_inspector/conf/pxe_filter.py @@ -0,0 +1,35 @@ +# 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 + +from ironic_inspector.common.i18n import _ + + +_OPTS = [ + cfg.StrOpt('driver', default='iptables', + help=_('PXE boot filter driver to use, such as iptables')), + cfg.IntOpt('sync_period', default=15, min=0, + deprecated_name='firewall_update_period', + deprecated_group='firewall', + help=_('Amount of time in seconds, after which repeat periodic ' + 'update of the filter.')), +] + + +def register_opts(conf): + conf.register_opts(_OPTS, 'pxe_filter') + + +def list_opts(): + return _OPTS diff --git a/ironic_inspector/conf/swift.py b/ironic_inspector/conf/swift.py new file mode 100644 index 000000000..d6c5f66c9 --- /dev/null +++ b/ironic_inspector/conf/swift.py @@ -0,0 +1,54 @@ +# 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 + +from ironic_inspector.common.i18n import _ +from ironic_inspector.common import keystone + + +SWIFT_GROUP = 'swift' + + +_OPTS = [ + cfg.IntOpt('max_retries', + default=2, + help=_('Maximum number of times to retry a Swift request, ' + 'before failing.')), + cfg.IntOpt('delete_after', + default=0, + help=_('Number of seconds that the Swift object will last ' + 'before being deleted. (set to 0 to never delete the ' + 'object).')), + cfg.StrOpt('container', + default='ironic-inspector', + help=_('Default Swift container to use when creating ' + 'objects.')), + cfg.StrOpt('os_service_type', + default='object-store', + help=_('Swift service type.')), + cfg.StrOpt('os_endpoint_type', + default='internalURL', + help=_('Swift endpoint type.')), + cfg.StrOpt('os_region', + help=_('Keystone region to get endpoint for.')), +] + + +def register_opts(conf): + conf.register_opts(_OPTS, SWIFT_GROUP) + keystone.register_auth_opts(SWIFT_GROUP) + + +def list_opts(): + return keystone.add_auth_options(_OPTS) diff --git a/ironic_inspector/main.py b/ironic_inspector/main.py index d186a7b92..8c508dff2 100644 --- a/ironic_inspector/main.py +++ b/ironic_inspector/main.py @@ -16,7 +16,6 @@ import os import re import flask -from oslo_config import cfg from oslo_utils import uuidutils import werkzeug @@ -25,14 +24,15 @@ from ironic_inspector.common import context from ironic_inspector.common.i18n import _ from ironic_inspector.common import ironic as ir_utils from ironic_inspector.common import swift -from ironic_inspector import conf # noqa +import ironic_inspector.conf +from ironic_inspector.conf import opts as conf_opts from ironic_inspector import introspect from ironic_inspector import node_cache from ironic_inspector import process from ironic_inspector import rules from ironic_inspector import utils -CONF = cfg.CONF +CONF = ironic_inspector.conf.CONF app = flask.Flask(__name__) @@ -45,7 +45,7 @@ _LOGGING_EXCLUDED_KEYS = ('logs',) def _get_version(): - ver = flask.request.headers.get(conf.VERSION_HEADER, + ver = flask.request.headers.get(conf_opts.VERSION_HEADER, _DEFAULT_API_VERSION) try: requested = tuple(int(x) for x in ver.split('.')) @@ -103,8 +103,8 @@ def check_api_version(): @app.after_request def add_version_headers(res): - res.headers[conf.MIN_VERSION_HEADER] = '%s.%s' % MINIMUM_API_VERSION - res.headers[conf.MAX_VERSION_HEADER] = '%s.%s' % CURRENT_API_VERSION + res.headers[conf_opts.MIN_VERSION_HEADER] = '%s.%s' % MINIMUM_API_VERSION + res.headers[conf_opts.MAX_VERSION_HEADER] = '%s.%s' % CURRENT_API_VERSION return res diff --git a/ironic_inspector/plugins/capabilities.py b/ironic_inspector/plugins/capabilities.py index a75171d9c..9725c4f4f 100644 --- a/ironic_inspector/plugins/capabilities.py +++ b/ironic_inspector/plugins/capabilities.py @@ -15,38 +15,11 @@ from oslo_config import cfg -from ironic_inspector.common.i18n import _ from ironic_inspector.plugins import base from ironic_inspector import utils -DEFAULT_CPU_FLAGS_MAPPING = { - 'vmx': 'cpu_vt', - 'svm': 'cpu_vt', - 'aes': 'cpu_aes', - 'pse': 'cpu_hugepages', - 'pdpe1gb': 'cpu_hugepages_1g', - 'smx': 'cpu_txt', -} - -CAPABILITIES_OPTS = [ - cfg.BoolOpt('boot_mode', - default=False, - help=_('Whether to store the boot mode (BIOS or UEFI).')), - cfg.DictOpt('cpu_flags', - default=DEFAULT_CPU_FLAGS_MAPPING, - help=_('Mapping between a CPU flag and a capability to set ' - 'if this flag is present.')), -] - - -def list_opts(): - return [ - ('capabilities', CAPABILITIES_OPTS) - ] - CONF = cfg.CONF -CONF.register_opts(CAPABILITIES_OPTS, group='capabilities') LOG = utils.getProcessingLogger(__name__) diff --git a/ironic_inspector/plugins/discovery.py b/ironic_inspector/plugins/discovery.py index 0b32bc62a..9b65251a3 100644 --- a/ironic_inspector/plugins/discovery.py +++ b/ironic_inspector/plugins/discovery.py @@ -21,21 +21,7 @@ from ironic_inspector import node_cache from ironic_inspector import utils -DISCOVERY_OPTS = [ - cfg.StrOpt('enroll_node_driver', - default='fake', - help=_('The name of the Ironic driver used by the enroll ' - 'hook when creating a new node in Ironic.')), -] - - -def list_opts(): - return [ - ('discovery', DISCOVERY_OPTS) - ] - CONF = cfg.CONF -CONF.register_opts(DISCOVERY_OPTS, group='discovery') LOG = utils.getProcessingLogger(__name__) diff --git a/ironic_inspector/test/base.py b/ironic_inspector/test/base.py index 887098866..bd97b272f 100644 --- a/ironic_inspector/test/base.py +++ b/ironic_inspector/test/base.py @@ -25,7 +25,8 @@ from oslo_utils import uuidutils from oslotest import base as test_base from ironic_inspector.common import i18n -from ironic_inspector import conf +import ironic_inspector.conf +from ironic_inspector.conf import opts as conf_opts from ironic_inspector import db from ironic_inspector import introspection_state as istate from ironic_inspector import node_cache @@ -33,7 +34,7 @@ from ironic_inspector.plugins import base as plugins_base from ironic_inspector.test.unit import policy_fixture from ironic_inspector import utils -CONF = conf.cfg.CONF +CONF = ironic_inspector.conf.CONF class BaseTest(test_base.BaseTestCase): @@ -64,7 +65,7 @@ class BaseTest(test_base.BaseTestCase): self.cfg.set_default('connection', "sqlite:///", group='database') self.cfg.set_default('slave_connection', None, group='database') self.cfg.set_default('max_retries', 10, group='database') - conf.parse_args([], default_config_files=[]) + conf_opts.parse_args([], default_config_files=[]) self.policy = self.useFixture(policy_fixture.PolicyFixture()) def assertPatchEqual(self, expected, actual): diff --git a/ironic_inspector/test/unit/test_keystone.py b/ironic_inspector/test/unit/test_keystone.py index 3d9d4cf5d..14a7aa84e 100644 --- a/ironic_inspector/test/unit/test_keystone.py +++ b/ironic_inspector/test/unit/test_keystone.py @@ -49,8 +49,7 @@ class KeystoneTest(base.BaseTest): self.assertEqual(auth1, sess.auth) def test_add_auth_options(self): - group, opts = keystone.add_auth_options([], TESTGROUP)[0] - self.assertEqual(TESTGROUP, group) + opts = keystone.add_auth_options([]) # check that there is no duplicates names = {o.dest for o in opts} self.assertEqual(len(names), len(opts)) diff --git a/ironic_inspector/test/unit/test_main.py b/ironic_inspector/test/unit/test_main.py index 7da31883e..31b5c1743 100644 --- a/ironic_inspector/test/unit/test_main.py +++ b/ironic_inspector/test/unit/test_main.py @@ -16,11 +16,11 @@ import json import unittest import mock -from oslo_config import cfg from oslo_utils import uuidutils from ironic_inspector.common import ironic as ir_utils -from ironic_inspector import conf +import ironic_inspector.conf +from ironic_inspector.conf import opts as conf_opts from ironic_inspector import introspect from ironic_inspector import introspection_state as istate from ironic_inspector import main @@ -32,7 +32,7 @@ from ironic_inspector import rules from ironic_inspector.test import base as test_base from ironic_inspector import utils -CONF = cfg.CONF +CONF = ironic_inspector.conf.CONF def _get_error(res): @@ -431,7 +431,7 @@ class TestApiRules(BaseAPITest): create_mock.return_value = mock.Mock(spec=rules.IntrospectionRule, **{'as_dict.return_value': exp}) - headers = {conf.VERSION_HEADER: + headers = {conf_opts.VERSION_HEADER: main._format_version((1, 5))} res = self.app.post('/v1/rules', data=json.dumps(data), @@ -510,9 +510,9 @@ class TestApiMisc(BaseAPITest): class TestApiVersions(BaseAPITest): def _check_version_present(self, res): self.assertEqual('%d.%d' % main.MINIMUM_API_VERSION, - res.headers.get(conf.MIN_VERSION_HEADER)) + res.headers.get(conf_opts.MIN_VERSION_HEADER)) self.assertEqual('%d.%d' % main.CURRENT_API_VERSION, - res.headers.get(conf.MAX_VERSION_HEADER)) + res.headers.get(conf_opts.MAX_VERSION_HEADER)) def test_root_endpoint(self): res = self.app.get("/") @@ -578,14 +578,14 @@ class TestApiVersions(BaseAPITest): self.app.post('/v1/introspection/foobar')) def test_request_correct_version(self): - headers = {conf.VERSION_HEADER: + headers = {conf_opts.VERSION_HEADER: main._format_version(main.CURRENT_API_VERSION)} self._check_version_present(self.app.get('/', headers=headers)) def test_request_unsupported_version(self): bad_version = (main.CURRENT_API_VERSION[0], main.CURRENT_API_VERSION[1] + 1) - headers = {conf.VERSION_HEADER: + headers = {conf_opts.VERSION_HEADER: main._format_version(bad_version)} res = self.app.get('/', headers=headers) self._check_version_present(res) diff --git a/setup.cfg b/setup.cfg index a80001287..bbc730210 100644 --- a/setup.cfg +++ b/setup.cfg @@ -62,14 +62,9 @@ ironic_inspector.pxe_filter = iptables = ironic_inspector.pxe_filter.iptables:IptablesFilter noop = ironic_inspector.pxe_filter.base:NoopFilter oslo.config.opts = - ironic_inspector = ironic_inspector.conf:list_opts - ironic_inspector.common.ironic = ironic_inspector.common.ironic:list_opts - ironic_inspector.common.swift = ironic_inspector.common.swift:list_opts - ironic_inspector.plugins.discovery = ironic_inspector.plugins.discovery:list_opts - ironic_inspector.plugins.capabilities = ironic_inspector.plugins.capabilities:list_opts - ironic_inspector.plugins.pci_devices = ironic_inspector.plugins.pci_devices:list_opts + ironic_inspector = ironic_inspector.conf.opts:list_opts oslo.config.opts.defaults = - ironic_inspector = ironic_inspector.conf:set_config_defaults + ironic_inspector = ironic_inspector.conf.opts:set_config_defaults oslo.policy.enforcer = ironic_inspector = ironic_inspector.policy:get_oslo_policy_enforcer oslo.policy.policies =