diff --git a/api-ref/source/baremetal-api-v1-inspection-rules.inc b/api-ref/source/baremetal-api-v1-inspection-rules.inc new file mode 100644 index 0000000000..a90b576912 --- /dev/null +++ b/api-ref/source/baremetal-api-v1-inspection-rules.inc @@ -0,0 +1,260 @@ +.. -*- rst -*- + +=================================== +Inspection rules (inspection_rules) +=================================== + +Inspection Rules consist of conditions that evaluate against inspection data +and actions that run on a node when conditions are met during inspection. + +.. versionadded:: 1.96 + Inspection Rules API was introduced. + +Create Inspection Rule +====================== + +.. rest_method:: POST /v1/inspection_rules + +Creates an inspection rule. + +.. versionadded:: 1.96 + Inspection Rules API was introduced. + +Normal response codes: 201 + +Error response codes: 400, 401, 403, 409 + +Request +------- + +.. rest_parameters:: parameters.yaml + + - uuid: req_uuid + - description: inspection_rule_description + - conditions: inspection_rule_conditions + - actions: inspection_rule_actions + - phase: inspection_rule_phase + - priority: inspection_rule_priority + - sensitive: inspection_rule_sensitive + +Request Inspection Rule Condition +--------------------------------- + +.. rest_parameters:: parameters.yaml + + - op: inspection_rule_condition_op + - args: inspection_rule_condition_args + - loop: inspection_rule_condition_loop + - multiple: inspection_rule_condition_multiple + +Request Inspection Rule Action +------------------------------ + +.. rest_parameters:: parameters.yaml + + - op: inspection_rule_action_op + - args: inspection_rule_action_args + - loop: inspection_rule_action_loop + +Request Example +--------------- + +.. literalinclude:: samples/inspection-rule-create-request.json + :language: javascript + +Response Parameters +------------------- + +.. rest_parameters:: parameters.yaml + + - uuid: uuid + - description: inspection_rule_description + - conditions: inspection_rule_conditions + - actions: inspection_rule_actions + - phase: inspection_rule_phase + - priority: inspection_rule_priority + - sensitive: inspection_rule_sensitive + - created_at: created_at + - updated_at: updated_at + - links: links + +Response Example +---------------- + +.. literalinclude:: samples/inspection-rule-create-response.json + :language: javascript + +List Inspection Rules +===================== + +.. rest_method:: GET /v1/inspection_rules + +Lists all inspection rules. + +.. versionadded:: 1.96 + Inspection Rules API was introduced. + +Normal response codes: 200 + +Error response codes: 400, 401, 403, 404 + +Request +------- + +.. rest_parameters:: parameters.yaml + + - detail: detail + - phase: req_inspection_rule_phase + +Response Parameters +------------------- + +.. rest_parameters:: parameters.yaml + + - uuid: uuid + - description: inspection_rule_description + - phase: inspection_rule_phase + - priority: inspection_rule_priority + - sensitive: inspection_rule_sensitive + - created_at: created_at + - updated_at: updated_at + - links: links + - conditions: inspection_rule_conditions + - actions: inspection_rule_actions + +Response Example +---------------- + +**Example inspection rule list response:** + +.. literalinclude:: samples/inspection-rule-list-response.json + :language: javascript + +**Example detailed inspection rule list response:** + +.. literalinclude:: samples/inspection-rule-detail-response.json + :language: javascript + +Show Inspection Rule Details +============================ + +.. rest_method:: GET /v1/inspection_rules/{rule_id} + +Shows details for an inspection rule. + +.. versionadded:: 1.96 + Inspection Rules API was introduced. + +Normal response codes: 200 + +Error response codes: 400, 401, 403, 404 + +Request +------- + +.. rest_parameters:: parameters.yaml + + - rule_id: inspection_rule_ident + +Response Parameters +------------------- + +.. rest_parameters:: parameters.yaml + + - uuid: uuid + - description: inspection_rule_description + - conditions: inspection_rule_conditions + - actions: inspection_rule_actions + - phase: inspection_rule_phase + - priority: inspection_rule_priority + - sensitive: inspection_rule_sensitive + - created_at: created_at + - updated_at: updated_at + - links: links + +Response Example +---------------- + +.. literalinclude:: samples/inspection-rule-show-response.json + :language: javascript + +Update an Inspection Rule +========================= + +.. rest_method:: PATCH /v1/inspection_rules/{rule_id} + +Update an inspection rule. + +.. versionadded:: 1.96 + Inspection Rules API was introduced. + +Normal response code: 200 + +Error response codes: 400, 401, 403, 404, 409 + +Request +------- + +The BODY of the PATCH request must be a JSON PATCH document, adhering to +`RFC 6902 `_. + +.. rest_parameters:: parameters.yaml + + - rule_id: inspection_rule_ident + +.. literalinclude:: samples/inspection-rule-update-request.json + :language: javascript + +Response +-------- + +.. rest_parameters:: parameters.yaml + + - uuid: uuid + - description: inspection_rule_description + - conditions: inspection_rule_conditions + - actions: inspection_rule_actions + - phase: inspection_rule_phase + - priority: inspection_rule_priority + - sensitive: inspection_rule_sensitive + - created_at: created_at + - updated_at: updated_at + - links: links + +.. literalinclude:: samples/inspection-rule-update-response.json + :language: javascript + +Delete Inspection Rule +====================== + +.. rest_method:: DELETE /v1/inspection_rules/{rule_id} + +Deletes an inspection rule. + +.. versionadded:: 1.96 + Inspection Rules API was introduced. + +Normal response codes: 204 + +Error response codes: 400, 401, 403, 404 + +Request +------- + +.. rest_parameters:: parameters.yaml + + - rule_id: inspection_rule_ident + +Delete All Inspection Rules +=========================== + +.. rest_method:: DELETE /v1/inspection_rules + +Deletes all non-built-in inspection rules. + +.. versionadded:: 1.96 + Inspection Rules API was introduced. + +Normal response codes: 204 + +Error response codes: 400, 401, 403 diff --git a/api-ref/source/index.rst b/api-ref/source/index.rst index b153fe6a8a..5c01f7919e 100644 --- a/api-ref/source/index.rst +++ b/api-ref/source/index.rst @@ -33,6 +33,7 @@ .. include:: baremetal-api-v1-nodes-history.inc .. include:: baremetal-api-v1-nodes-inventory.inc .. include:: baremetal-api-v1-shards.inc +.. include:: baremetal-api-v1-inspection-rules.inc .. NOTE(dtantsur): keep chassis close to the end since it's semi-deprecated .. include:: baremetal-api-v1-chassis.inc .. NOTE(dtantsur): keep misc last, since it covers internal API diff --git a/api-ref/source/parameters.yaml b/api-ref/source/parameters.yaml index 421b8809b3..d8fb0b2ea3 100644 --- a/api-ref/source/parameters.yaml +++ b/api-ref/source/parameters.yaml @@ -1156,6 +1156,106 @@ inspection_finished_at: in: body required: true type: string +inspection_rule_action_args: + description: | + A list (in the sense of Python ``*args``) + or a dict (in the sense of Python ``**kwargs``) with arguments for + the action operator. + in: body + required: true + type: array +inspection_rule_action_loop: + description: | + This is an Ansible-style loop field. It contains a list or dictionary + of items to iterate over for the same action. + in: body + required: false + type: array +inspection_rule_action_op: + description: | + The operator to execute with specified arguments when conditions are met. + in: body + required: true + type: string +inspection_rule_actions: + description: | + A list of actions to run during inspection. An action is a dictionary + or list, with required keys 'op' and 'args', and optional key 'loop'. + in: body + required: true + type: array +inspection_rule_condition_args: + description: | + A list (in the sense of Python ``*args``) + or a dict (in the sense of Python ``**kwargs``) with arguments for + the condition operator. + in: body + required: true + type: array +inspection_rule_condition_loop: + description: | + This is an Ansible-style loop field. It contains a list or dictionary + of items to iterate over for the same condition. + in: body + required: false + type: array +inspection_rule_condition_multiple: + description: | + Determines how the results of all loop iterations are combined, whether + a condition is returned as true if 'any' check passes, + or only when 'all'; the 'first', or the 'last' check is true. + in: body + required: false + type: string +inspection_rule_condition_op: + description: | + The operator to run conditions by, with specified arguments. + in: body + required: true + type: string +inspection_rule_conditions: + description: | + A list of conditions to check before applying the rule. A + condition is a dictionary or list, with required keys 'op' and 'args', and + optional keys 'loop' and 'multiple'. + in: body + required: false + type: array +inspection_rule_description: + description: | + Informational text about this rule. + in: body + required: false + type: string +inspection_rule_ident: + description: | + The UUID of the inspection rule. + in: body + required: false + type: string +inspection_rule_phase: + description: | + Specifies the phase when the rule should run, defaults to 'main'. + in: body + required: false + type: string +inspection_rule_priority: + description: | + A non-negative integer priority for the rule. Specifies the rule's + precedence level during execution. Priorities between 0 and 9999 can be + used by all rules, negative value and values above 10000 are reserved for + built-in rules. The default priority is 0. + in: body + required: false + type: int +inspection_rule_sensitive: + description: | + Indicates whether the rule contains sensitive information. A sensitive + rule will also have the ability to see sensitive fields on inspection + data. + in: body + required: false + type: string inspection_started_at: description: | The UTC date and time when the hardware inspection was started, @@ -1735,6 +1835,12 @@ req_inspect_interface: in: body required: false type: string +req_inspection_rule_phase: + description: | + Specifies the phase when the rule should run, defaults to 'main'. + in: body + required: false + type: string req_instance_info: description: | Information used to customize the deployed image. May include root partition diff --git a/api-ref/source/samples/inspection-rule-create-request.json b/api-ref/source/samples/inspection-rule-create-request.json new file mode 100644 index 0000000000..3641623bfc --- /dev/null +++ b/api-ref/source/samples/inspection-rule-create-request.json @@ -0,0 +1,34 @@ +{ + "description": "BMC credentials", + "phase": "main", + "priority": 100, + "sensitive": true, + "conditions": [ + { + "op": "contains", + "args": {"value": "{inventory[system_vendor][manufacturer]}", "regex": "(?i)dell"} + }, + { + "op": "is-true", + "args": {"value": "{node.auto_discovered}"} + } + ], + "actions": [ + { + "op": "set-attribute", + "args": {"path": "/driver", "value": "idrac"} + }, + { + "op": "set-attribute", + "args": {"path": "driver_info.redfish_address", "value": "https://{inventory[bmc_address]}"} + }, + { + "op": "set-attribute", + "args": {"path": "/driver_info/redfish_username", "value": "admin"} + }, + { + "op": "set-attribute", + "args": {"path": "/driver_info/redfish_password", "value": "password"} + } + ] + } diff --git a/api-ref/source/samples/inspection-rule-create-response.json b/api-ref/source/samples/inspection-rule-create-response.json new file mode 100644 index 0000000000..0b22f4687d --- /dev/null +++ b/api-ref/source/samples/inspection-rule-create-response.json @@ -0,0 +1,21 @@ +{ + "created_at": "2025-03-18T22:28:48.643434+11:11", + "description": "BMC credentials", + "phase": "main", + "priority": 100, + "sensitive": true, + "actions": null, + "conditions": null, + "links": [ + { + "href": "http://10.60.253.180:6385/v1/inspection_rules/783bf33a-a8e3-1e23-a645-1e95a1f95186", + "rel": "self" + }, + { + "href": "http://10.60.253.180:6385/inspection_rules/783bf33a-a8e3-1e23-a645-1e95a1f95186", + "rel": "bookmark" + } + ], + "updated_at": null, + "uuid": "783bf33a-a8e3-1e23-a645-1e95a1f95186" + } diff --git a/api-ref/source/samples/inspection-rule-detail-response.json b/api-ref/source/samples/inspection-rule-detail-response.json new file mode 100644 index 0000000000..0afd047f1d --- /dev/null +++ b/api-ref/source/samples/inspection-rule-detail-response.json @@ -0,0 +1,43 @@ +{ + "inspection_rules": [ + { + "created_at": "2025-03-14T15:37:29.542187+00:00", + "description": "Set properties on discovered data", + "phase": "main", + "priority": 50, + "sensitive": false, + "conditions": [ + { + "op": "is-true", + "args": {"value": "{inventory[cpu][count]}"} + } + ], + "actions": [ + { + "op": "set-attribute", + "args": {"path": "/properties/cpus", "value": "{inventory[cpu][count]}"} + }, + { + "op": "set-attribute", + "args": {"path": "/properties/memory_mb", "value": "{inventory[memory][physical_mb]}"} + }, + { + "op": "set-attribute", + "args": {"path": "/properties/cpu_arch", "value": "{inventory[cpu][architecture]}"} + } + ], + "links": [ + { + "href": "http://10.60.253.180:6385/v1/inspection_rules/75a6c1f7-2de0-47b3-9c54-8e6ef3a27bcd", + "rel": "self" + }, + { + "href": "http://10.60.253.180:6385/inspection_rules/75a6c1f7-2de0-47b3-9c54-8e6ef3a27bcd", + "rel": "bookmark" + } + ], + "updated_at": null, + "uuid": "783bf33a-a8e3-1e23-a645-1e95a1f95186" + } + ] + } diff --git a/api-ref/source/samples/inspection-rule-list-response.json b/api-ref/source/samples/inspection-rule-list-response.json new file mode 100644 index 0000000000..f9d41ed8b9 --- /dev/null +++ b/api-ref/source/samples/inspection-rule-list-response.json @@ -0,0 +1,55 @@ +{ + "inspection_rules": [ + { + "description": "BMC credentials", + "phase": "main", + "priority": 100, + "sensitive": true, + "links": [ + { + "href": "http://10.60.253.180:6385/v1/inspection_rules/783bf33a-a8e3-1e23-a645-1e95a1f95186", + "rel": "self" + }, + { + "href": "http://10.60.253.180:6385/inspection_rules/783bf33a-a8e3-1e23-a645-1e95a1f95186", + "rel": "bookmark" + } + ], + "uuid": "783bf33a-a8e3-1e23-a645-1e95a1f95186" + }, + { + "description": "Set properties on discovered data", + "phase": "main", + "priority": 50, + "sensitive": false, + "links": [ + { + "href": "http://10.60.253.180:6385/v1/inspection_rules/1f3ee449-08cd-9e3f-e1e5-9cfda674081a", + "rel": "self" + }, + { + "href": "http://10.60.253.180:6385/inspection_rules/1f3ee449-08cd-9e3f-e1e5-9cfda674081a", + "rel": "bookmark" + } + ], + "uuid": "1f3ee449-08cd-9e3f-e1e5-9cfda674081a" + }, + { + "description": "Memory systems", + "phase": "main", + "priority": 0, + "sensitive": false, + "links": [ + { + "href": "http://10.60.253.180:6385/v1/inspection_rules/210055f4-7367-ff8d-ae42-f4f9e8e85e8a", + "rel": "self" + }, + { + "href": "http://10.60.253.180:6385/inspection_rules/210055f4-7367-ff8d-ae42-f4f9e8e85e8a", + "rel": "bookmark" + } + ], + "uuid": "210055f4-7367-ff8d-ae42-f4f9e8e85e8a" + } + ] + } diff --git a/api-ref/source/samples/inspection-rule-show-response.json b/api-ref/source/samples/inspection-rule-show-response.json new file mode 100644 index 0000000000..8b015f9272 --- /dev/null +++ b/api-ref/source/samples/inspection-rule-show-response.json @@ -0,0 +1,39 @@ +{ + "created_at": "2025-03-18T22:28:48.643434+11:11", + "description": "Set properties on discovered data", + "phase": "main", + "priority": 50, + "sensitive": false, + "conditions": [ + { + "op": "is-true", + "args": {"value": "{inventory[cpu][count]}"} + } + ], + "actions": [ + { + "op": "set-attribute", + "args": {"path": "/properties/cpus", "value": "{inventory[cpu][count]}"} + }, + { + "op": "set-attribute", + "args": {"path": "/properties/memory_mb", "value": "{inventory[memory][physical_mb]}"} + }, + { + "op": "set-attribute", + "args": {"path": "/properties/cpu_arch", "value": "{inventory[cpu][architecture]}"} + } + ], + "links": [ + { + "href": "http://10.60.253.180:6385/v1/inspection_rules/1f3ee449-08cd-9e3f-e1e5-9cfda674081a", + "rel": "self" + }, + { + "href": "http://10.60.253.180:6385/inspection_rules/1f3ee449-08cd-9e3f-e1e5-9cfda674081a", + "rel": "bookmark" + } + ], + "updated_at": null, + "uuid": "1f3ee449-08cd-9e3f-e1e5-9cfda674081a" + } diff --git a/api-ref/source/samples/inspection-rule-update-request.json b/api-ref/source/samples/inspection-rule-update-request.json new file mode 100644 index 0000000000..7bccbe0d9c --- /dev/null +++ b/api-ref/source/samples/inspection-rule-update-request.json @@ -0,0 +1,28 @@ +[ + { + "path": "/description", + "value": "Updated rule for setting hardware properties", + "op": "replace" + }, + { + "path": "/priority", + "value": 75, + "op": "replace" + }, + { + "path": "/conditions/0", + "value": { + "op": "is-true", + "args": {"value": "{inventory[cpu][count]}"} + }, + "op": "replace" + }, + { + "path": "/actions/-", + "value": { + "op": "set-attribute", + "args": {"path": "/properties/local_gb", "value": "{inventory[disks][0][size]}"} + }, + "op": "add" + } + ] diff --git a/api-ref/source/samples/inspection-rule-update-response.json b/api-ref/source/samples/inspection-rule-update-response.json new file mode 100644 index 0000000000..9a5e267e92 --- /dev/null +++ b/api-ref/source/samples/inspection-rule-update-response.json @@ -0,0 +1,43 @@ +{ + "created_at": "2025-03-23T22:28:48.643434+11:11", + "description": "Updated rule for setting hardware properties", + "phase": "main", + "priority": 75, + "sensitive": false, + "conditions": [ + { + "op": "is-true", + "args": {"value": "{inventory[cpu][count]}"} + } + ], + "actions": [ + { + "op": "set-attribute", + "args": {"path": "/properties/cpus", "value": "{inventory[cpu][count]}"} + }, + { + "op": "set-attribute", + "args": {"path": "/properties/memory_mb", "value": "{inventory[memory][physical_mb]}"} + }, + { + "op": "set-attribute", + "args": {"path": "/properties/cpu_arch", "value": "{inventory[cpu][architecture]}"} + }, + { + "op": "set-attribute", + "args": {"path": "/properties/local_gb", "value": "{inventory[disks][0][size]}"} + } + ], + "links": [ + { + "href": "http://10.60.253.180:6385/v1/inspection_rules/1f3ee449-08cd-9e3f-e1e5-9cfda674081a", + "rel": "self" + }, + { + "href": "http://10.60.253.180:6385/inspection_rules/1f3ee449-08cd-9e3f-e1e5-9cfda674081a", + "rel": "bookmark" + } + ], + "uuid": "1f3ee449-08cd-9e3f-e1e5-9cfda674081a", + "updated_at": "2025-03-24T11:42:18.763029+00:00" + } diff --git a/doc/source/admin/inspection.rst b/doc/source/admin/inspection.rst index a08e7d784a..3f5e58d112 100644 --- a/doc/source/admin/inspection.rst +++ b/doc/source/admin/inspection.rst @@ -8,9 +8,7 @@ Overview Inspection allows Bare Metal service to discover required node properties once required ``driver_info`` fields (for example, IPMI credentials) are set by an operator. Inspection will also create the Bare Metal service ports for the -discovered ethernet MACs. Operators will have to manually delete the Bare Metal -service ports for which physical media is not connected. This is required due -to the `bug 1405131 `_. +discovered ethernet MACs. There are three kinds of inspection supported by Bare Metal service: diff --git a/doc/source/admin/inspection/index.rst b/doc/source/admin/inspection/index.rst index aa2e3700ce..18147487b4 100644 --- a/doc/source/admin/inspection/index.rst +++ b/doc/source/admin/inspection/index.rst @@ -31,6 +31,161 @@ ironic-inspector_ service. pxe_filter migration +Inspection rules have now been migrate into Ironic as of 2025.1 "Epoxy" +release. This does not include support for reapplying inspection on +already stored data, nor does it support the ``"scope"`` field. + +The scope field allowed a rule to be applied only to specific nodes with +matching scope value rather than all nodes where conditions are met. + +:ironic-inspector-doc:`Inspection rules ` + +Inspection Rules +---------------- + +.. _inspection_rules: + +An inspection rule consists of conditions to check, and actions to run. +If conditions evaluate to true on the inspection data, then actions are +run on a node. + +Ironic provides an API to manage such rules. There are also built-in rules +which are pre-saved and loaded from a YAML file and cannot be CRUD through +the API. + +Available conditions and actions are defined by an extendedable set of +plugins. + +Refer to the +`Ironic API reference for inspection rules `_ +for information on how to CRUD inspection rules. + +Actions & Conditions +~~~~~~~~~~~~~~~~~~~~ +Conditions and actions have the same base structure: + +* ``op`` - operation: either boolean (conditions) or an action (actions). +* ``args`` - a list (in the sense of Python ``*args``) + or a dict (in the sense of Python ``**kwargs``) with arguments. + +Conditions +^^^^^^^^^^ + +Available conditions include: + +* ``is-true(value)`` - Check if value evaluates to boolean True. + This operator supports booleans, non-zero numbers and strings "yes", "true". +* ``is-false(value)`` - Check if value evaluates to boolean False. + Supports booleans, zero, None and strings "no", "false". +* ``is-none(value)`` - Check if value is None. +* ``is-empty(value)`` - Check if value is None or an empty string, + list or a dictionary. +* ``eq/lt/gt(*values, *, force_strings=False)`` - Check if all values are + equal, less/greater than. If force_strings, all values will be converted + to strings first before the check. +* ``in-net(address, subnet)`` - Check if the given address is in the provided + subnet. +* ``contains(value, regex)`` - Check if the value contains the given regular + expression. +* ``matches(value, regex)`` - Check if the value fully matches the given + regular expression. +* ``one-of(value, values)`` - Check if the value is in the provided list. + Similar to contains, but also works for non-string values. + +To check for the inverse of any of these conditions, prefix the operator with +an exclamation mark (with an optional space) before the op. E.g. +``eq`` - ``!eq``. + +Actions +^^^^^^^ + +Available actions include: + +* ``fail(msg)`` - Fail inspection with the given message. +* ``set-plugin-data(path, value)`` - Set a value in the plugin data. +* ``extend-plugin-data(path, value, *, unique=False)`` - Treat a value in the + plugin data as a list, append to it. If unique is True, do not append if the + item exists. +* ``unset-plugin-data(path)`` - Unset a value in the plugin data. +* ``log(msg, level="info")`` - Write the message to the Ironic logs. +* ``set-attribute(path, value)`` - Set the given path + (in the sense of JSON patch) to the value. +* ``extend-attribute(path, value, *, unique=False)`` - Treat the given path + as a list, append to it. +* ``del-attribute(path)`` - Unset the given path. Fails on invalid node + attributes, but does not fail on missing subdict fields. +* ``set-port-attribute(port_id, path, value)`` - Set value on the port + identified by a MAC or a UUID. +* ``extend-port-attribute(port_id, path, value, *, unique=False)`` - Treat the + given path on the port as a list, append to it. +* ``del-port-attribute(port_id, path)`` - Unset value on the port identified + by a MAC or a UUID. + +Loops +^^^^^ +Both conditions and actions accept an optional ``loop`` argument of list of +items to iterate over for the same condition or action. + +The ``loop`` field supports an Ansible-style loop (for reference, see +`Ansible loops documentation `_ +). + +In conditions, there's an additional (and optional) ``multiple`` field which is +only applicable when the loop field is present. It determines how the results +of all loop iterations are combined: + +* ``any`` (default) - returns ``True`` if any iteration's result is ``True`` +* ``all`` - returns ``True`` only if all iterations' results are ``True`` +* ``first`` - returns the result of the first iteration only, skipping + remaining iterations if the first is ``True`` +* ``last`` - uses only the result from the last iteration, effectively + ignoring previous iterations + +For example, this condition check will return true if at any time of the +iteration, the 'system' is any of the models in the ``loop`` list: + +.. code-block:: yaml + + - op: eq + args: ["{inventory.system.product_name}", "{item}"] + loop: ["HPE ProLiant DL380 Gen10", "PowerEdge R640", "Cisco UCS"] + multiple: any + +Whereas in actions, each iteration of the loop executes same action with the +current item value. + +Example of setting multiple attributes using loop: + +.. code-block:: yaml + + - op: set-attribute + args: ["{item[path]}", "{item[value]}"] + loop: + - {path: "/driver_info/ipmi_username", value: "admin"} + - {path: "/driver_info/ipmi_password", value: "password"} + - {path: "/driver_info/ipmi_address", value: "{inventory[bmc_address]}"} + +.. note:: + Both dot (``"driver_info.ipmi_username"``) and + slash (``"driver_info/ipmi_username"``) notation paths are supported. + +Variable Interpolation +^^^^^^^^^^^^^^^^^^^^^^ + + {"action": "set-attribute", "path": "/driver_info/ipmi_address", + "value": "{data[inventory][bmc_address]}"} + +On a rule execution, values enclosed with braces, usually ``value``, ``msg``, +``address``, and ``subnet`` fields in both actions and conditions, will be +treated as replacement fields and formatted to a string using +`python string formatting notation `_. + +If the value of any of these keys is a dict or list, strings nested at any +level within the structure will be recursively formatted as well:: + + {"action": "set-attribute", "path": "/properties/root_device", + "value": {"serial": "{data[root_device][serial]}"}} + Configuration ------------- diff --git a/doc/source/admin/inspection/migration.rst b/doc/source/admin/inspection/migration.rst index 6cc1d94e01..a3a812cc4e 100644 --- a/doc/source/admin/inspection/migration.rst +++ b/doc/source/admin/inspection/migration.rst @@ -32,8 +32,7 @@ This list currently includes: `_. :ironic-inspector-doc:`Inspection rules ` -are also currently not implemented but are planned for the 2024.2 release or -later. +have now been implemented as of 2025.1 "Epoxy" release. New defaults ~~~~~~~~~~~~