Skip to content

fix: resolve from_pool string names to pool IDs in object spec#862

Open
FragmentedPacket wants to merge 1 commit intoinfrahub-developfrom
object-templates-vlan-pools
Open

fix: resolve from_pool string names to pool IDs in object spec#862
FragmentedPacket wants to merge 1 commit intoinfrahub-developfrom
object-templates-vlan-pools

Conversation

@FragmentedPacket
Copy link
Contributor

@FragmentedPacket FragmentedPacket commented Mar 6, 2026

Problem

When loading objects via YAML spec files, attributes using from_pool with a plain string pool name are passed through unchanged:

vlan_id:
  from_pool: "my-vlan-pool"

This causes failures at the API level because Infrahub expects the pool reference in {id: uuid} form:

vlan_id:
  from_pool:
    id: "185b9728-1b76-dda7-d13d-106529b1bcd9"

Fix

Add _resolve_attribute_pool to InfrahubObjectFileData that:

  1. Detects when an attribute value has from_pool as a plain string
  2. Looks up the pool by HFID using client.get(kind=pool_kind, hfid=[name])
  3. Replaces the string with {"id": pool.id} before the node is created

A _ATTRIBUTE_KIND_TO_POOL_KIND mapping controls which attribute kinds are eligible — currently NumberCoreNumberPool.

Values that are already {"from_pool": {"id": ...}} (dict form) pass through unchanged, so existing usage is unaffected.

Changes

  • infrahub_sdk/spec/object.py: add _ATTRIBUTE_KIND_TO_POOL_KIND mapping and _resolve_attribute_pool classmethod; call it in create_node when processing attributes

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of pool references in attributes during node creation. Attribute pool references are now properly resolved and dereferenced when creating nodes.

…sing

When loading objects via YAML spec files, attributes using `from_pool`
with a plain string pool name (e.g. `{"from_pool": "my-vlan-pool"}`)
were passed through as-is, causing failures because the API expects
`{"from_pool": {"id": "<uuid>"}}`.

Add `_resolve_attribute_pool` to `InfrahubObjectFileData` which looks up
the pool by HFID and replaces the string with the resolved `{id: uuid}`
form before creating the node. Currently supports Number attributes
via `CoreNumberPool`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@FragmentedPacket FragmentedPacket requested a review from a team as a code owner March 6, 2026 05:25
@github-actions github-actions bot added the type/documentation Improvements or additions to documentation label Mar 6, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 6, 2026

Walkthrough

The changes introduce functionality to resolve attribute values that reference pools during node creation. A module-level mapping is added to associate attribute kinds with their corresponding pool kinds. A new classmethod _resolve_attribute_pool is implemented in the InfrahubObjectFileData class to query appropriate pools via the Infrahub client and replace values with pool references containing identifiers. The create_node method is updated to apply this new resolution logic when processing attribute values.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: resolving from_pool string names to pool IDs in object spec, which is the core objective of this PR.
Description check ✅ Passed The description covers the problem, solution, and implementation details comprehensively. However, it lacks sections for 'How to review', 'How to test', and 'Checklist' from the template.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link

Deploying infrahub-sdk-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: db8b798
Status: ✅  Deploy successful!
Preview URL: https://27ded294.infrahub-sdk-python.pages.dev
Branch Preview URL: https://object-templates-vlan-pools.infrahub-sdk-python.pages.dev

View logs

@codecov
Copy link

codecov bot commented Mar 6, 2026

Codecov Report

❌ Patch coverage is 29.41176% with 12 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
infrahub_sdk/spec/object.py 29.41% 11 Missing and 1 partial ⚠️
@@                 Coverage Diff                  @@
##           infrahub-develop     #862      +/-   ##
====================================================
- Coverage             80.64%   80.57%   -0.07%     
====================================================
  Files                   118      118              
  Lines                 10246    10262      +16     
  Branches               1534     1538       +4     
====================================================
+ Hits                   8263     8269       +6     
- Misses                 1455     1465      +10     
  Partials                528      528              
Flag Coverage Δ
integration-tests 40.33% <29.41%> (-0.03%) ⬇️
python-3.10 51.80% <29.41%> (-0.03%) ⬇️
python-3.11 51.80% <29.41%> (-0.03%) ⬇️
python-3.12 51.80% <29.41%> (-0.03%) ⬇️
python-3.13 51.80% <29.41%> (-0.03%) ⬇️
python-3.14 53.49% <29.41%> (-0.03%) ⬇️
python-filler-3.12 24.00% <0.00%> (-0.04%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
infrahub_sdk/spec/object.py 82.18% <29.41%> (-3.01%) ⬇️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@FragmentedPacket FragmentedPacket changed the base branch from develop to infrahub-develop March 6, 2026 05:34
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@infrahub_sdk/spec/object.py`:
- Around line 433-455: The _resolve_attribute_pool flow currently always treats
a string from_pool as an HFID lookup; update
InfrahubObject._resolve_attribute_pool to first detect if from_pool is a UUID
string and, if so, return the value with from_pool set to {"id": from_pool}
immediately (before calling client.get). Use the existing local variable
from_pool and the attr_schema/_ATTRIBUTE_KIND_TO_POOL_KIND checks as before;
only call client.get(kind=pool_kind, hfid=[from_pool], ...) when from_pool is
not a UUID.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b7bdfb09-e8e1-448e-a558-25ffa43574d9

📥 Commits

Reviewing files that changed from the base of the PR and between f737549 and db8b798.

📒 Files selected for processing (1)
  • infrahub_sdk/spec/object.py

Comment on lines +433 to +455
@classmethod
async def _resolve_attribute_pool(
cls,
client: InfrahubClient,
schema: MainSchemaTypesAPI,
name: str,
value: Any,
branch: str | None = None,
) -> Any:
"""If an attribute value has from_pool as a plain string name, resolve it to {id: uuid}."""
if not isinstance(value, dict) or "from_pool" not in value:
return value
from_pool = value["from_pool"]
if not isinstance(from_pool, str):
return value
attr_schema = schema.get_attribute_or_none(name=name)
if attr_schema is None:
return value
pool_kind = _ATTRIBUTE_KIND_TO_POOL_KIND.get(attr_schema.kind)
if pool_kind is None:
return value
pool = await client.get(kind=pool_kind, hfid=[from_pool], branch=branch, raise_when_missing=True)
return {**value, "from_pool": {"id": pool.id}}
Copy link

@coderabbitai coderabbitai bot Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Handle UUID from_pool strings before doing an HFID lookup.

Right now every plain string goes through hfid=[from_pool] on Line 454. If callers pass a pool UUID string instead of a name, this path misses the direct-id case even though the mutation payload wants {"id": "<uuid>"}.

💡 Suggested fix
     async def _resolve_attribute_pool(
         cls,
         client: InfrahubClient,
         schema: MainSchemaTypesAPI,
         name: str,
         value: Any,
         branch: str | None = None,
     ) -> Any:
         """If an attribute value has from_pool as a plain string name, resolve it to {id: uuid}."""
         if not isinstance(value, dict) or "from_pool" not in value:
             return value
         from_pool = value["from_pool"]
         if not isinstance(from_pool, str):
             return value
+        if is_valid_uuid(from_pool):
+            return {**value, "from_pool": {"id": from_pool}}
         attr_schema = schema.get_attribute_or_none(name=name)
         if attr_schema is None:
             return value
         pool_kind = _ATTRIBUTE_KIND_TO_POOL_KIND.get(attr_schema.kind)
         if pool_kind is None:
             return value
         pool = await client.get(kind=pool_kind, hfid=[from_pool], branch=branch, raise_when_missing=True)
         return {**value, "from_pool": {"id": pool.id}}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@infrahub_sdk/spec/object.py` around lines 433 - 455, The
_resolve_attribute_pool flow currently always treats a string from_pool as an
HFID lookup; update InfrahubObject._resolve_attribute_pool to first detect if
from_pool is a UUID string and, if so, return the value with from_pool set to
{"id": from_pool} immediately (before calling client.get). Use the existing
local variable from_pool and the attr_schema/_ATTRIBUTE_KIND_TO_POOL_KIND checks
as before; only call client.get(kind=pool_kind, hfid=[from_pool], ...) when
from_pool is not a UUID.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the bot highlights a valid point here, since we have is_valid_uuid, we could check if the string is a valid UUID prior to making a HFID-based query. That would spare us a possible useless query.

Also can you add a test to validate how the fix should behave and prevent possible regressions?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find test files related to spec/object or InfrahubObjectFileData
fd -e py . tests/ | xargs grep -l "object\|InfrahubObjectFileData\|create_node\|resolve_attribute" 2>/dev/null | head -20

# Also look at the test directory structure
tree tests/ -L 3 2>/dev/null || find tests/ -type f -name "*.py" | head -30

Length of output: 5195


🏁 Script executed:

#!/bin/bash
cat tests/unit/sdk/spec/test_object.py
echo "---SEPARATOR---"
cat tests/unit/sdk/pool/test_attribute_from_pool.py
echo "---SEPARATOR---"
cat tests/unit/sdk/pool/conftest.py

Length of output: 26453


🏁 Script executed:

#!/bin/bash
# Check if there's a conftest in the spec directory
cat tests/unit/sdk/spec/conftest.py 2>/dev/null || echo "NO SPEC CONFTEST"

# Also check the unit/sdk conftest.py for client_with_schema_01 and schema setup
cat tests/unit/sdk/conftest.py

echo "---SEPARATOR---"
# Look at the pool conftest for vlan_schema
cat tests/unit/sdk/pool/conftest.py | grep -A 60 "vlan_schema"

Length of output: 88643


@gmazoyer, agreed on both points — the UUID fast-path is a valid improvement that avoids a redundant network round-trip. Here's the plan:

  • Apply UUID fast-path in _resolve_attribute_pool before the HFID query
  • Add unit tests for _resolve_attribute_pool directly, covering all four cases

💡 Use @coderabbitai plan to create a plan for code changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type/documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants