Skip to content

feat(protocols): regenerate protocols with peer-typed relationships [IFC-3054] - #1285

Open
ogenstad wants to merge 2 commits into
infrahub-developfrom
pog-sdk-core-protocols-artifact-IFC-3054
Open

feat(protocols): regenerate protocols with peer-typed relationships [IFC-3054]#1285
ogenstad wants to merge 2 commits into
infrahub-developfrom
pog-sdk-core-protocols-artifact-IFC-3054

Conversation

@ogenstad

@ogenstad ogenstad commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Why

Follow-up to #1273, which taught the generator to render this module but deliberately did not
regenerate it. This is the regenerated artifact.

Until now infrahub_sdk/protocols.py came from a second Jinja template kept in the Infrahub
repository, which had drifted from the generator behind infrahubctl protocols: it emitted bare
RelatedNode and RelationshipManager, so the protocols we ship lost the peer type of every
relationship. invoke backend.generate in Infrahub now feeds the processed core schema through the
generator from #1273, so this module and the protocols a user generates for their own schema come
from one renderer and cannot drift apart again.

It also carries a one-line generator fix, because the two are entangled: the sort key decides the
artifact's ordering, so landing them separately would mean regenerating this file twice and
resolving a conflict on the golden fixtures for no gain.

Non-goals: no other hand-written code changes.

Part of IFC-3054. Needs the matching Infrahub change, which is not merged yet, so do not regenerate
from Infrahub develop until that lands.

What changed

Ordering fix (generator.py, one line)

Models were sorted on the schema name without its namespace, so BuiltinIPPrefix sorted under
IPPrefix. That key is also not unique: a kind is its namespace plus its name, so two kinds sharing
a name tie, and the tie fell to whatever order the schema was supplied in. This file is committed
and validated by regenerating it and diffing, so once such a pair exists that becomes a build
failing intermittently with unchanged inputs. There is no such pair in the core schema today, which
is why it is worth fixing before someone hits it.

Sorting on (kind.lower(), kind) makes the ordering total. kind is the name each class renders
as, and every schema type the generator accepts exposes it. Case is ignored so the file still reads
alphabetically, with the kind itself breaking ties, because a case-insensitive key on its own
compares InfraDevice and INfraDEvice equal and reintroduces the same problem. As a side effect
this keeps this module's existing class order, so the artifact diff below is content only.

For users: regenerating with infrahubctl protocols reorders the classes in their file and changes
nothing else.

Regenerated protocols

  • Every relationship carries its peer type. node.rel.peer and node.many_rel.peers[0].peer
    resolve to the peer's protocol instead of a bare InfrahubNode.
  • Cardinality-one relationships use the RelationshipAttribute descriptor, so they can be assigned
    an id, an HFID, a peer node or None and still read back as a typed RelatedNode. Previously
    assigning an id was a type error, despite being what the runtime supports.
  • The relationships the API exposes implicitly are present: member_of_groups,
    subscriber_of_groups, profiles.
  • Eight new classes: the ProfileBuiltinIPAddress, ProfileBuiltinIPPrefix, ProfileBuiltinTag
    and ProfileIpamNamespace kinds in both variants.
  • Attributes that always hold a value are no longer optional, and each attribute follows its schema
    kind. CoreGlobalPermission.decision and CoreObjectPermission.decision become Integer rather
    than Enum, which is the type the API actually returns.
  • CoreGenericAccount.tokens and .external_identities are gone. Their peers are internal, so
    /api/schema never exposed them: the module was advertising two relationships the API does not
    have. Nothing in this repository or in Infrahub consumes them.
  • Protocols generated for a user's own schema now import the four Profile* kinds above instead of
    redefining them, which is part of why the golden fixtures move. That import is at runtime, so
    from schema_protocols import ProfileBuiltinTag keeps working.

What stayed the same

  • No class is removed and no member is dropped other than the two relationships above. Verified by
    parsing both versions and diffing the class and member sets.
  • Class order is unchanged: 0 of the 182 existing classes move position.
  • commit on CoreGenericRepository, added in chore(schema): add commit to the CoreGenericRepository protocol [IFC-2954] #1272, is retained. It moves within its class only,
    because attributes are sorted by name.
  • Inherited members are now restated on subclasses, which is most of the size increase. The classes
    still inherit, so this is verbosity rather than a change in meaning.

How to review

Suggested order:

  1. infrahub_sdk/protocols_generator/generator.py, one line, plus
    test_render_order_does_not_depend_on_input_order. It covers the two ways a weaker key can tie,
    two kinds sharing a name and two names differing only in case, and asserts that supplying the
    schema in either order renders identically.
  2. The artifact. It is generated output, so the useful checks are structural: spot-check one class
    you know well. CoreGenericRepository is a good one, gaining peer types, credential becoming
    RelationshipAttribute[CoreCredential], and member_of_groups and subscriber_of_groups
    appearing.
  3. The golden fixtures, which show the effect on user-facing output: the import line, the four
    Profile* classes becoming imports, and the reordering.

Regenerating is the real check on the artifact, but it needs the Infrahub side, so it cannot be done
from this repository alone.

How to test

uv run invoke format lint-code
uv run pytest tests/unit

ruff, ty and mypy are clean over the regenerated module, which is what mattered most here given it
is now about 2,200 lines with descriptor annotations.

From an Infrahub checkout with the matching branch, uv run invoke backend.validate-generated
exits 0, and generating twice produces an identical file. Rendering in six separate processes with
four fixed PYTHONHASHSEED values plus two random ones also produces an identical SHA-256.

Impact & rollout

  • Backward compatibility: additive except for the two internal-peer relationships and the
    decision fields changing from str to int. Both are listed above and in the changelog.
  • Deployment notes: merge before the Infrahub PR that switches generation over, since that one
    bumps the submodule pointer to include this commit.

Checklist

  • Tests added/updated
  • Changelog entry added
  • External docs updated (if user-facing or ops-facing change)
  • Internal .md docs updated (internal knowledge and AI code tools knowledge)

@codecov

codecov Bot commented Aug 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

@@                 Coverage Diff                  @@
##           infrahub-develop    #1285      +/-   ##
====================================================
+ Coverage             84.46%   85.33%   +0.87%     
====================================================
  Files                   147      148       +1     
  Lines                 13296    14085     +789     
  Branches               1930     1936       +6     
====================================================
+ Hits                  11230    12020     +790     
+ Misses                 1503     1499       -4     
- Partials                563      566       +3     
Flag Coverage Δ
integration-tests 43.40% <99.92%> (+3.23%) ⬆️
python-3.10 60.16% <100.00%> (+2.35%) ⬆️
python-3.11 60.17% <100.00%> (+2.38%) ⬆️
python-3.12 60.17% <100.00%> (+2.38%) ⬆️
python-3.13 60.16% <100.00%> (+2.37%) ⬆️
python-3.14 60.17% <100.00%> (+2.37%) ⬆️
python-filler-3.12 21.93% <0.00%> (-1.31%) ⬇️

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

Files with missing lines Coverage Δ
infrahub_sdk/protocols.py 100.00% <100.00%> (ø)
infrahub_sdk/protocols_generator/generator.py 88.28% <100.00%> (-6.84%) ⬇️

... 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.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 4 files

Re-trigger cubic

@ogenstad
ogenstad force-pushed the pog-sdk-core-protocols-artifact-IFC-3054 branch from ab2d4ad to 75a0631 Compare August 27, 2026 07:55
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 27, 2026

Copy link
Copy Markdown

Deploying infrahub-sdk-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: fe31f2a
Status: ✅  Deploy successful!
Preview URL: https://6e332eeb.infrahub-sdk-python.pages.dev
Branch Preview URL: https://pog-sdk-core-protocols-artif.infrahub-sdk-python.pages.dev

View logs

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 7 files

Re-trigger cubic

@ogenstad
ogenstad force-pushed the pog-sdk-core-protocols-artifact-IFC-3054 branch from 75a0631 to ba1fffd Compare August 27, 2026 10:04

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 7 files

Re-trigger cubic

The models were sorted on the schema name without its namespace, so BuiltinIPPrefix
sorted under IPPrefix, and two kinds sharing a name were left in whatever order the
caller supplied them. The rendered module is committed and validated by regenerating
it and diffing, so an ordering that depends on the input order can turn into a build
that fails intermittently once such a pair exists.

Sort on the kind instead, which is the name each class renders as. Case is ignored so
the file still reads alphabetically, with the kind itself breaking ties, since a
case-insensitive key on its own would compare InfraDevice and INfraDEvice equal and
reintroduce the same problem. This also keeps the order the protocols module shipped
with before it moved to this generator.
…IFC-3054]

Regenerated by "invoke backend.generate", which now renders this module through the
SDK's own code generator instead of a separate template kept in the Infrahub
repository. That template had drifted: it emitted bare RelatedNode and
RelationshipManager, dropping the peer type of every relationship.

Every relationship now carries its peer, cardinality-one relationships use the
assignable RelationshipAttribute descriptor, and the module gains the relationships
the API exposes implicitly along with four Profile kinds it was missing. Attributes
follow their schema kind and are no longer optional when they always hold a value.

CoreGenericAccount.tokens and .external_identities are gone. Their peers are
internal, so /api/schema never exposed them and nothing consumes them.

The golden fixtures move because the four Profile kinds are now importable from this
module, so protocols generated for a user schema import them instead of redefining
them.
@ogenstad
ogenstad force-pushed the pog-sdk-core-protocols-artifact-IFC-3054 branch from ba1fffd to fe31f2a Compare August 27, 2026 10:56

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 7 files

Re-trigger cubic

@ogenstad
ogenstad marked this pull request as ready for review August 27, 2026 13:13
@ogenstad
ogenstad requested a review from a team as a code owner August 27, 2026 13:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants