ironic_inspector package¶
Subpackages¶
- ironic_inspector.cmd package
- ironic_inspector.common package
- Submodules
- ironic_inspector.common.context module
- ironic_inspector.common.coordination module
- ironic_inspector.common.ironic module
- ironic_inspector.common.keystone module
- ironic_inspector.common.lldp_parsers module
- ironic_inspector.common.lldp_tlvs module
- ironic_inspector.common.locking module
- ironic_inspector.common.rpc module
- ironic_inspector.common.rpc_service module
- ironic_inspector.common.service_utils module
- ironic_inspector.common.swift module
- Module contents
- ironic_inspector.conductor package
- ironic_inspector.conf package
- Submodules
- ironic_inspector.conf.accelerators module
- ironic_inspector.conf.capabilities module
- ironic_inspector.conf.coordination module
- ironic_inspector.conf.default module
- ironic_inspector.conf.discovery module
- ironic_inspector.conf.dnsmasq_pxe_filter module
- ironic_inspector.conf.extra_hardware module
- ironic_inspector.conf.iptables module
- ironic_inspector.conf.ironic module
- ironic_inspector.conf.opts module
- ironic_inspector.conf.pci_devices module
- ironic_inspector.conf.port_physnet module
- ironic_inspector.conf.processing module
- ironic_inspector.conf.pxe_filter module
- ironic_inspector.conf.service_catalog module
- ironic_inspector.conf.swift module
- Module contents
- ironic_inspector.plugins package
- Submodules
- ironic_inspector.plugins.accel_device module
- ironic_inspector.plugins.base module
- ironic_inspector.plugins.base_physnet module
- ironic_inspector.plugins.capabilities module
- ironic_inspector.plugins.discovery module
- ironic_inspector.plugins.example module
- ironic_inspector.plugins.extra_hardware module
- ironic_inspector.plugins.introspection_data module
- ironic_inspector.plugins.lldp_basic module
- ironic_inspector.plugins.local_link_connection module
- ironic_inspector.plugins.pci_devices module
- ironic_inspector.plugins.physnet_cidr_map module
- ironic_inspector.plugins.raid_device module
- ironic_inspector.plugins.rules module
- ironic_inspector.plugins.standard module
- Module contents
- ironic_inspector.pxe_filter package
- Submodules
- ironic_inspector.pxe_filter.base module
- ironic_inspector.pxe_filter.dnsmasq module
- ironic_inspector.pxe_filter.interface module
- ironic_inspector.pxe_filter.iptables module
- Module contents
Submodules¶
ironic_inspector.api_tools module¶
Generic Rest Api tools.
- ironic_inspector.api_tools.limit_field(value)[source]¶
Fetch the pagination limit field from flask.request.args.
- Returns:
the limit
- ironic_inspector.api_tools.marker_field(value)[source]¶
Fetch the pagination marker field from flask.request.args.
- Returns:
an uuid
ironic_inspector.db module¶
SQLAlchemy models for inspection data and shared database code.
- class ironic_inspector.db.Node(**kwargs)[source]¶
Bases:
Base
- error¶
- finished_at¶
- manage_boot¶
- started_at¶
- state¶
- uuid¶
- version_id¶
- class ironic_inspector.db.Rule(**kwargs)[source]¶
Bases:
Base
- actions¶
- conditions¶
- created_at¶
- description¶
- disabled¶
- scope¶
- uuid¶
- class ironic_inspector.db.RuleCondition(**kwargs)[source]¶
Bases:
Base
- field¶
- id¶
- invert¶
- multiple¶
- op¶
- params¶
- rule¶
- ironic_inspector.db.get_context_manager()[source]¶
Create transaction context manager lazily.
- Returns:
The transaction context manager.
- ironic_inspector.db.get_reader_session()[source]¶
Help method to get reader session.
- Returns:
The reader session.
- ironic_inspector.db.get_writer_session()[source]¶
Help method to get writer session.
- Returns:
The writer session.
ironic_inspector.introspect module¶
Handling introspection request.
ironic_inspector.introspection_state module¶
Introspection state.
- class ironic_inspector.introspection_state.Events[source]¶
Bases:
object
Events that change introspection state.
- abort = 'abort'¶
- abort_end = 'abort_end'¶
- error = 'error'¶
- finish = 'finish'¶
- process = 'process'¶
- reapply = 'reapply'¶
- start = 'start'¶
- timeout = 'timeout'¶
- wait = 'wait'¶
ironic_inspector.main module¶
- ironic_inspector.main.api(path, is_public_api=False, rule=None, verb_to_rule_map=None, **flask_kwargs)[source]¶
Decorator to wrap api methods.
Performs flask routing, exception conversion, generation of oslo context for request and API access policy enforcement.
- Parameters:
path – flask app route path
is_public_api – whether this API path should be treated as public, with minimal access enforcement
rule – API access policy rule to enforce. If rule is None, the ‘default’ policy rule will be enforced, which is “deny all” if not overridden in policy confif file.
verb_to_rule_map – if both rule and this are given, defines mapping between http verbs (uppercase) and strings to format the ‘rule’ string with
kwargs – all the rest kwargs are passed to flask app.route
- ironic_inspector.main.generate_introspection_status(node)[source]¶
Return a dict representing current node status.
- Parameters:
node – a NodeInfo instance
- Returns:
dictionary
ironic_inspector.node_cache module¶
Cache for nodes currently under introspection.
- class ironic_inspector.node_cache.NodeInfo(uuid, version_id=None, state=None, started_at=None, finished_at=None, error=None, node=None, ports=None, ironic=None, manage_boot=True)[source]¶
Bases:
object
Record about a node in the cache.
This class optionally allows to acquire a lock on a node. Note that the class instance itself is NOT thread-safe, you need to create a new instance for every thread.
- acquire_lock(blocking=True)[source]¶
Acquire a lock on the associated node.
Exits with success if a lock is already acquired using this NodeInfo object.
- Parameters:
blocking – if True, wait for lock to be acquired, otherwise return immediately.
- Returns:
boolean value, whether lock was acquired successfully
- add_attribute(name, value, session=None)[source]¶
Store look up attribute for a node in the database.
- Parameters:
name – attribute name
value – attribute value or list of possible values
session – optional existing database session
- add_trait(trait, ironic=None)[source]¶
Add a trait to the node.
- Parameters:
trait – trait to add
ironic – Ironic client to use instead of self.ironic
- property attributes¶
Node look up attributes as a dict.
- create_ports(ports, ironic=None)[source]¶
Create one or several ports for this node.
- Parameters:
ports – List of ports with all their attributes e.g [{‘mac’: xx, ‘ip’: xx, ‘client_id’: None}, {‘mac’: xx, ‘ip’: None, ‘client_id’: None}] It also support the old style of list of macs. A warning is issued if port already exists on a node.
ironic – Ironic client to use instead of self.ironic
- delete_port(port, ironic=None)[source]¶
Delete port.
- Parameters:
port – port object or its MAC
ironic – Ironic client to use instead of self.ironic
- finished(event, error=None)[source]¶
Record status for this node and process a terminal transition.
Also deletes look up attributes from the cache.
- Parameters:
event – the event to process
error – error message
- fsm_event(event, strict=False)[source]¶
Update node_info.state based on a fsm.process_event(event) call.
An AutomatonException triggers an error event. If strict, node_info.finished(istate.Events.error, error=str(exc)) is called with the AutomatonException instance and a EventError raised.
- Parameters:
event – an event to process by the fsm
- Strict:
whether to fail the introspection upon an invalid event
- Raises:
NodeStateInvalidEvent
- get_by_path(path)[source]¶
Get field value by ironic-style path (e.g. /extra/foo).
- Parameters:
path – path to a field
- Returns:
field value
- Raises:
KeyError if field was not found
- property ironic¶
Ironic client instance.
- property manage_boot¶
Whether to manage boot for this node.
- property options¶
Node introspection options as a dict.
- patch(patches, ironic=None, **kwargs)[source]¶
Apply JSON patches to a node.
Refreshes cached node instance.
- Parameters:
patches – JSON patches to apply
ironic – Ironic client to use instead of self.ironic
kwargs – Arguments to pass to ironicclient.
- Raises:
openstacksdk exceptions
- patch_port(port, patches, ironic=None)[source]¶
Apply JSON patches to a port.
- Parameters:
port – port object or its MAC
patches – JSON patches to apply
ironic – Ironic client to use instead of self.ironic
- ports(ironic=None)[source]¶
Get Ironic port objects associated with the cached node record.
This value is cached as well, use invalidate_cache() to clean.
- Returns:
dict MAC -> port object
- release_lock()[source]¶
Release a lock on a node.
Does nothing if lock was not acquired using this NodeInfo object.
- remove_trait(trait, ironic=None)[source]¶
Remove a trait from the node.
- Parameters:
trait – trait to add
ironic – Ironic client to use instead of self.ironic
- replace_field(path, func, **kwargs)[source]¶
Replace a field on ironic node.
- Parameters:
path – path to a field as used by the ironic client
func – function accepting an old value and returning a new one
kwargs – if ‘default’ value is passed here, it will be used when no existing value is found.
- Raises:
KeyError if value is not found and default is not set
- Raises:
everything that patch() may raise
- property state¶
State of the node_info object.
- update_capabilities(ironic=None, **caps)[source]¶
Update capabilities on a node.
- Parameters:
caps – capabilities to update
ironic – Ironic client to use instead of self.ironic
- update_properties(ironic=None, **props)[source]¶
Update properties on a node.
- Parameters:
props – properties to update
ironic – Ironic client to use instead of self.ironic
- property version_id¶
Get the version id
- ironic_inspector.node_cache.active_macs()[source]¶
List all MAC’s that are on introspection right now.
- ironic_inspector.node_cache.add_node(uuid, state, manage_boot=True, **attributes)[source]¶
Store information about a node under introspection.
All existing information about this node is dropped. Empty values are skipped.
- Parameters:
uuid – Ironic node UUID
state – The initial state of the node
manage_boot – whether to manage boot for this node
attributes – attributes known about this node (like macs, BMC etc); also ironic client instance may be passed under ‘ironic’
- Returns:
NodeInfo
- ironic_inspector.node_cache.clean_up()[source]¶
Clean up the cache.
Finish introspection for timed out nodes.
- Returns:
list of timed out node UUID’s
- ironic_inspector.node_cache.create_node(driver, ironic=None, **attributes)[source]¶
Create ironic node and cache it.
Create new node in ironic.
Cache it in inspector.
Sets node_info state to enrolling.
- Parameters:
driver – driver for Ironic node.
ironic – ironic client instance.
attributes – dict, additional keyword arguments to pass to the ironic client on node creation.
- Returns:
NodeInfo, or None in case error happened.
- ironic_inspector.node_cache.delete_nodes_not_in_list(uuids)[source]¶
Delete nodes which don’t exist in Ironic node UUIDs.
- Parameters:
uuids – Ironic node UUIDs
- ironic_inspector.node_cache.find_node(**attributes)[source]¶
Find node in cache.
Looks up a node based on attributes in a best-match fashion. This function acquires a lock on a node.
- Parameters:
attributes – attributes known about this node (like macs, BMC etc) also ironic client instance may be passed under ‘ironic’
- Returns:
structure NodeInfo with attributes
uuid
andcreated_at
- Raises:
Error if node is not found or multiple nodes match the attributes
- ironic_inspector.node_cache.fsm_event_after(event, strict=False)[source]¶
Trigger an fsm event after the function execution.
It is assumed the first function arg of the decorated function is always a NodeInfo instance.
- Parameters:
event – the event to process after the function call
strict – make an invalid fsm event trigger an error event
- ironic_inspector.node_cache.fsm_event_before(event, strict=False)[source]¶
Trigger an fsm event before the function execution.
It is assumed the first function arg of the decorated function is always a NodeInfo instance.
- Parameters:
event – the event to process before the function call
strict – make an invalid fsm event trigger an error event
- ironic_inspector.node_cache.fsm_transition(event, reentrant=True, **exc_kwargs)[source]¶
Decorate a function to perform a (non-)reentrant transition.
If True, reentrant transition will be performed at the end of a function call. If False, the transition will be performed before the function call. The function is decorated with the triggers_fsm_error_transition decorator as well.
- Parameters:
event – the event to bind the transition to.
reentrant – whether the transition is reentrant.
exc_kwargs – passed on to the triggers_fsm_error_transition decorator
- ironic_inspector.node_cache.get_introspection_data(node_id, processed=True)[source]¶
Get introspection data for this node.
- Parameters:
node_id – node UUID.
processed – Specify the type of introspected data, set to False indicates retrieving the unprocessed data.
- Returns:
A dictionary representation of intropsected data
- ironic_inspector.node_cache.get_node(node_id, ironic=None)[source]¶
Get node from cache.
- Parameters:
node_id – node UUID or name.
ironic – optional ironic client instance
- Returns:
structure NodeInfo.
- ironic_inspector.node_cache.get_node_list(ironic=None, marker=None, limit=None)[source]¶
Get node list from the cache.
The list of the nodes is ordered based on the (started_at, uuid) attribute pair, newer items first.
- Parameters:
ironic – optional ironic client instance
marker – pagination marker (an UUID or None)
limit – pagination limit; None for default CONF.api_max_limit
- Returns:
a list of NodeInfo instances.
- ironic_inspector.node_cache.introspection_active()[source]¶
Check if introspection is active for at least one node.
- ironic_inspector.node_cache.record_node(ironic=None, bmc_addresses=None, macs=None)[source]¶
Create a cache record for a known active node.
- Parameters:
ironic – ironic client instance.
bmc_addresses – list of BMC addresses.
macs – list of MAC addresses.
- Returns:
NodeInfo
- ironic_inspector.node_cache.release_lock(func)[source]¶
Decorate a node_info-function to release the node_info lock.
Assumes the first parameter of the function func is always a NodeInfo instance.
- ironic_inspector.node_cache.start_introspection(uuid, **kwargs)[source]¶
Start the introspection of a node.
If a node_info record exists in the DB, a start transition is used rather than dropping the record in order to check for the start transition validity in particular node state.
- Parameters:
uuid – Ironic node UUID
kwargs – passed on to add_node()
- Raises:
NodeStateInvalidEvent in case the start transition is invalid in the current node state
- Raises:
NodeStateRaceCondition if a mismatch was detected between the node_info cache and the DB
- Returns:
NodeInfo
- ironic_inspector.node_cache.store_introspection_data(node_id, introspection_data, processed=True)[source]¶
Store introspection data for this node.
- Parameters:
node_id – node UUID.
introspection_data – A dictionary of introspection data
processed – Specify the type of introspected data, set to False indicates the data is unprocessed.
- ironic_inspector.node_cache.triggers_fsm_error_transition(errors=(<class 'Exception'>, ), no_errors=(<class 'ironic_inspector.utils.NodeStateInvalidEvent'>, <class 'ironic_inspector.utils.NodeStateRaceCondition'>))[source]¶
Trigger an fsm error transition upon certain errors.
It is assumed the first function arg of the decorated function is always a NodeInfo instance.
- Parameters:
errors – a tuple of exceptions upon which an error event is triggered. Re-raised.
no_errors – a tuple of exceptions that won’t trigger the error event.
ironic_inspector.policy module¶
- ironic_inspector.policy.authorize(rule, target, creds, *args, **kwargs)[source]¶
A shortcut for policy.Enforcer.authorize()
Checks authorization of a rule against the target and credentials, and raises an exception if the rule is not defined. args and kwargs are passed directly to oslo.policy Enforcer.authorize Always returns True if CONF.auth_strategy != keystone.
- Parameters:
rule – name of a registered oslo.policy rule
target – dict-like structure to check rule against
creds – dict of policy values from request
- Returns:
True if request is authorized against given policy, False otherwise
- Raises:
oslo_policy.policy.PolicyNotRegistered if supplied policy is not registered in oslo_policy
- ironic_inspector.policy.get_enforcer()[source]¶
Provides access to the single instance of Policy enforcer.
- ironic_inspector.policy.get_oslo_policy_enforcer()[source]¶
Get the enforcer instance to generate policy files.
This method is for use by oslopolicy CLI scripts. Those scripts need the ‘output-file’ and ‘namespace’ options, but having those in sys.argv means loading the inspector config options will fail as those are not expected to be present. So we pass in an arg list with those stripped out.
- ironic_inspector.policy.init_enforcer(policy_file=None, rules=None, default_rule=None, use_conf=True)[source]¶
Synchronously initializes the policy enforcer
- Parameters:
policy_file – Custom policy file to use, if none is specified, CONF.oslo_policy.policy_file will be used.
rules – Default dictionary / Rules to use. It will be considered just in the first instantiation.
default_rule – Default rule to use, CONF.oslo_policy.policy_default_rule will be used if none is specified.
use_conf – Whether to load rules from config file.
ironic_inspector.process module¶
Handling introspection data from the ramdisk.
- ironic_inspector.process.get_introspection_data(uuid, processed=True, get_json=False)[source]¶
Get introspection data from the storage backend.
- Parameters:
uuid – node UUID
processed – Indicates the type of introspection data to be read, set True to request processed introspection data.
get_json – Specify whether return the introspection data in json format, string value is returned if False.
- Raises:
utils.Error
- ironic_inspector.process.process(introspection_data)[source]¶
Process data from the ramdisk.
This function heavily relies on the hooks to do the actual data processing.
- ironic_inspector.process.reapply(node_uuid, data=None)[source]¶
Re-apply introspection steps.
Re-apply preprocessing, postprocessing and introspection rules on stored data.
- Parameters:
node_uuid – node UUID
data – unprocessed introspection data to be reapplied
- Raises:
utils.Error
- ironic_inspector.process.store_introspection_data(node_uuid, data, processed=True)[source]¶
Store introspection data to the storage backend.
- Parameters:
node_uuid – node UUID
data – Introspection data to be saved
processed – The type of introspection data, set to True means the introspection data is processed, otherwise unprocessed.
- Raises:
utils.Error
ironic_inspector.rules module¶
Support for introspection rules.
- class ironic_inspector.rules.IntrospectionRule(uuid, conditions, actions, description, scope=None)[source]¶
Bases:
object
High-level class representing an introspection rule.
- apply_actions(node_info, data=None)[source]¶
Run actions on a node.
- Parameters:
node_info – NodeInfo instance
data – introspection data
- check_conditions(node_info, data)[source]¶
Check if conditions are true for a given node.
- Parameters:
node_info – a NodeInfo object
data – introspection data
- Returns:
True if conditions match, otherwise False
- check_scope(node_info)[source]¶
Check if node’s scope falls under rule._scope and rule is applicable
- Parameters:
node_info – a NodeInfo object
- Returns:
True if conditions match, otherwise False
- property description¶
- ironic_inspector.rules.create(conditions_json, actions_json, uuid=None, description=None, scope=None)[source]¶
Create a new rule in database.
- Parameters:
conditions_json – list of dicts with the following keys: * op - operator * field - JSON path to field to compare Other keys are stored as is.
actions_json – list of dicts with the following keys: * action - action type Other keys are stored as is.
uuid – rule UUID, will be generated if empty
description – human-readable rule description
scope – if scope on node and rule matches, rule applies; if its empty, rule applies to all nodes.
- Returns:
new IntrospectionRule object
- Raises:
utils.Error on failure
ironic_inspector.utils module¶
- class ironic_inspector.utils.DeferredBasicAuthMiddleware(app, auth_file)[source]¶
Bases:
object
Middleware which sets X-Identity-Status header based on authentication
- exception ironic_inspector.utils.Error(msg, code=400, log_level='error', **kwargs)[source]¶
Bases:
Exception
Inspector exception.
- exception ironic_inspector.utils.IntrospectionDataNotFound(msg, code=404, **kwargs)[source]¶
Bases:
NotFoundInCacheError
Introspection data not found.
- exception ironic_inspector.utils.IntrospectionDataStoreDisabled(msg, code=400, log_level='error', **kwargs)[source]¶
Bases:
Error
Introspection data store is disabled.
- exception ironic_inspector.utils.NoAvailableConductor(msg, **kwargs)[source]¶
Bases:
Error
No available conductor in the service group.
- exception ironic_inspector.utils.NodeStateInvalidEvent(msg, code=400, log_level='error', **kwargs)[source]¶
Bases:
Error
Invalid event attempted.
- exception ironic_inspector.utils.NodeStateRaceCondition(*args, **kwargs)[source]¶
Bases:
Error
State mismatch between the DB and a node_info.
- exception ironic_inspector.utils.NotFoundInCacheError(msg, code=404, **kwargs)[source]¶
Bases:
Error
Exception when node was not found in cache during processing.
- class ironic_inspector.utils.ProcessingLoggerAdapter(logger, extra)[source]¶
Bases:
KeywordArgumentAdapter
- process(msg, kwargs)[source]¶
Process the logging message and keyword arguments passed in to a logging call to insert contextual information. You can either manipulate the message itself, the keyword args or both. Return the message and kwargs modified (or not) to suit your needs.
Normally, you’ll only need to override this one method in a LoggerAdapter subclass for your specific needs.
- ironic_inspector.utils.add_auth_middleware(app)[source]¶
Add authentication middleware to Flask application.
- Parameters:
app – application.
- ironic_inspector.utils.add_basic_auth_middleware(app)[source]¶
Add HTTP Basic authentication middleware to Flask application.
- Parameters:
app – application.
- ironic_inspector.utils.add_cors_middleware(app)[source]¶
Create a CORS wrapper
Attach ironic-inspector-specific defaults that must be included in all CORS responses.
- Parameters:
app – application
- ironic_inspector.utils.check_auth(request, rule=None, target=None)[source]¶
Check authentication on request.
- Parameters:
request – Flask request
rule – policy rule to check the request against
target – dict-like structure to check rule against
- Raises:
utils.Error if access is denied
- ironic_inspector.utils.get_inventory(data, node_info=None)[source]¶
Get and validate the hardware inventory from introspection data.
- ironic_inspector.utils.get_valid_macs(data)[source]¶
Get a list of valid MAC’s from the introspection data.
- ironic_inspector.utils.iso_timestamp(timestamp=None, tz=<UTC>)[source]¶
Return an ISO8601-formatted timestamp (tz: UTC) or None.
- Parameters:
timestamp – such as time.time() or None
tz – timezone
- Returns:
an ISO8601-formatted timestamp, or None
- ironic_inspector.utils.processing_logger_prefix(data=None, node_info=None)[source]¶
Calculate prefix for logging.
Tries to use: * node UUID, node._state * node PXE MAC, * node BMC address
- Parameters:
data – introspection data
node_info – NodeInfo or ironic node object
- Returns:
logging prefix as a string