Component
infrahubctl
Infrahub SDK version
1.23.0 (current latest on PyPI)
Current Behavior
infrahubctl generator <name> exits immediately with:
Error: The node doesn't have an attribute for name
when the generator definition uses targets and the members of that group are of a kind that has no name attribute. The generator itself never runs, generate() is not called.
The CLI iterates over the group members and builds the params dict with a hardcoded name attribute, infrahub_sdk/ctl/generator.py:91:
for member in targets._get_relationship_many(name="members").peers:
check_parameter = {}
if identifier:
attribute = getattr(member.peer, identifier)
check_parameter = {identifier: attribute.value}
params = {"name": member.peer._get_attribute(name="name").value}
_get_attribute raises ResourceNotDefinedError when the attribute does not exist, infrahub_sdk/node/node.py:748. Not every kind has a name. In the customer schema the target kind is a firewall rule whose human_friendly_id and display_label are both rule_id__value, and its only attributes are rule_id, duration, changeid and status.
The query variables are not affected by this, they come from check_parameter, which is built correctly from the generator definition parameters. Only params on the generator instance needs the value.
Server side execution does not go through this code path, so the same generator works in a proposed change and fails only from the CLI.
Expected Behavior
infrahubctl generator <name> runs the generator for each member of the target group, whatever attributes the target kind happens to have.
Steps to Reproduce
- Define a kind with no
name attribute, for example:
- name: Rules
namespace: Firewall
human_friendly_id: ["rule_id__value"]
display_label: "{{ rule_id__value }}"
attributes:
- name: rule_id
kind: Number
- name: status
kind: Text
- Create a few nodes of that kind and add them to a
CoreStandardGroup called pending-firewall-rules
- Define a generator in
.infrahub.yml targeting that group:
generator_definitions:
- name: process_pending_rules
class_name: ProcessPendingRules
file_path: generators/pending_rules/process_pending.py
query: pending_rules_context
targets: pending-firewall-rules
parameters:
rule_id: rule_id__value
- Run
infrahubctl generator process_pending_rules
Additional Information
Workaround for now is to pass the variable explicitly, which takes the other branch in run() and skips the group iteration:
infrahubctl generator process_pending_rules rule_id=12345
That only runs one target per invocation, so it does not replace the group behaviour.
Reported by a customer running SDK 1.23.0 on Python 3.12.13.
Component
infrahubctl
Infrahub SDK version
1.23.0 (current latest on PyPI)
Current Behavior
infrahubctl generator <name>exits immediately with:when the generator definition uses
targetsand the members of that group are of a kind that has nonameattribute. The generator itself never runs,generate()is not called.The CLI iterates over the group members and builds the params dict with a hardcoded
nameattribute,infrahub_sdk/ctl/generator.py:91:_get_attributeraisesResourceNotDefinedErrorwhen the attribute does not exist,infrahub_sdk/node/node.py:748. Not every kind has aname. In the customer schema the target kind is a firewall rule whosehuman_friendly_idanddisplay_labelare bothrule_id__value, and its only attributes arerule_id,duration,changeidandstatus.The query variables are not affected by this, they come from
check_parameter, which is built correctly from the generator definition parameters. Onlyparamson the generator instance needs the value.Server side execution does not go through this code path, so the same generator works in a proposed change and fails only from the CLI.
Expected Behavior
infrahubctl generator <name>runs the generator for each member of the target group, whatever attributes the target kind happens to have.Steps to Reproduce
nameattribute, for example:CoreStandardGroupcalledpending-firewall-rules.infrahub.ymltargeting that group:infrahubctl generator process_pending_rulesAdditional Information
Workaround for now is to pass the variable explicitly, which takes the other branch in
run()and skips the group iteration:That only runs one target per invocation, so it does not replace the group behaviour.
Reported by a customer running SDK 1.23.0 on Python 3.12.13.