Skip to content

bug: Upsert not working for nodes that are assigning an attribute via a NumberPool and attribute in HFID #339

Description

@FragmentedPacket

Component

Python SDK

Infrahub SDK version

1.10.0

Current Behavior

Whenever we attempt to create an object such as a VLAN in an idempotent way when an attribute can use a CoreNumberPool such as vlan_id using the .save(allow_upsert=True), we run into the following error message:

[{'message': "invalid literal for int() with base 10: 'VLAN ID Pool - Test'", 'locations': [{'line': 3, 'column': 5}], 'path': ['InfraVLANUpsert']}]

If we omit allow_upsert=True, it assigns a VLAN ID, but we're not able to idempotently manage these objects so when using this in a generator, we have to attempt to fetch the VLAN from the DB and if it doesn't exist, and then create it rather than just creating the object and calling .save(allow_upsert=True).

Below is the full exception with the GraphQL query:

>>> vlan = client.create(kind="InfraVLAN", name="atl1_ilo_1", vlan_id=vlan_pool, site=site, status="Active", role="Management")
>>> vlan.save(allow_upsert=True)
URL: https://demo.infrahub.app/graphql/main
QUERY:

mutation {
    InfraVLANUpsert(
        data: {
            name: {
                value: "atl1_ilo_1"
            }
            vlan_id: {
                from_pool: {
                    id: "1832e9b4-e8b4-fcab-d4e4-1065092c9fee"
                }
            }
            status: {
                value: "Active"
            }
            role: {
                value: "Management"
            }
            site: {
                id: "1808d320-afbd-9656-d0e7-c515cf3a1de4"
            }
            hfid: [
                "atl1_ilo_1",
                "VLAN ID Pool - Test",
            ]
        }
    ){
        ok
        object {
            id
            vlan_id {
                value
            }
        }
    }
}

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/Mikhail/cloned/infrahub-sdk-python/infrahub_sdk/node.py", line 1741, in save
    self.create(allow_upsert=allow_upsert, timeout=timeout, request_context=request_context)
  File "/Users/Mikhail/cloned/infrahub-sdk-python/infrahub_sdk/node.py", line 1987, in create
    response = self._client.execute_graphql(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/Mikhail/cloned/infrahub-sdk-python/infrahub_sdk/client.py", line 1674, in execute_graphql
    raise GraphQLError(errors=response["errors"], query=query, variables=variables)
infrahub_sdk.exceptions.GraphQLError: An error occurred while executing the GraphQL Query
mutation {
    InfraVLANUpsert(
        data: {
            name: {
                value: "atl1_ilo_1"
            }
            vlan_id: {
                from_pool: {
                    id: "1832e9b4-e8b4-fcab-d4e4-1065092c9fee"
                }
            }
            status: {
                value: "Active"
            }
            role: {
                value: "Management"
            }
            site: {
                id: "1808d320-afbd-9656-d0e7-c515cf3a1de4"
            }
            hfid: [
                "atl1_ilo_1",
                "VLAN ID Pool - Test",
            ]
        }
    ){
        ok
        object {
            id
            vlan_id {
                value
            }
        }
    }
}
, [{'message': "invalid literal for int() with base 10: 'VLAN ID Pool - Test'", 'locations': [{'line': 3, 'column': 5}], 'path': ['InfraVLANUpsert']}]

Expected Behavior

Manage objects idempotently when we pull an attribute from a CoreNumberPool for the node. This is possible with CoreIPPrefixPool and CoreIPAddressPool.

Steps to Reproduce

  1. Log into https://demo.infrahub.app
  2. Create a resource pool for InfraVLAN for the vlan_id attribute
  3. Launch Python
from infrahub_sdk.client import InfrahubClientSync, Config
client = InfrahubClientSync(config=Config(address="https://demo.infrahub.app", username="otto", password="infrahub"))
vlan_pool = client.get(kind="CoreNumberPool", name__value="VLAN ID Pool - Test")
site = client.get(kind="LocationSite", name__value="atl1")
vlan = client.create(kind="InfraVLAN", name="atl1_ilo_1", vlan_id=vlan_pool, site=site, status="Active", role="Management")
vlan.save(allow_upsert=True)

Additional Information

No response

Activity

  1. dgarros commented on Apr 4, 2025

    @dgarros
    Contributor

    Just to be sure
    is it something that was working previously and that doesn't work anymore ? or it never worked ?

  2. FragmentedPacket commented on Apr 4, 2025

    @FragmentedPacket
    ContributorAuthor

    It has never worked since attempting to use the feature.

  3. added theissue type on May 23, 2025
  4. ogenstad commented on Aug 13, 2025

    @ogenstad
    Contributor

    This is a chicken and egg type of problem as we come with a dynamic pool and expect to find a specific vlan_id based on that pool. When we do something like this the call to vlan.save(allow_upsert=True) should raise an error. This also needs to be fixed in the Upsert mutation on the Infrahub side.

    Also document this behaviour so that it's clear why it doesn't work.

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

Metadata

Metadata

Labels

type/bugSomething isn't working as expected

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions