Show IP address version in GraphQL queries #7693

Closed
opened 2025-12-29 20:27:10 +01:00 by adam · 1 comment
Owner

Originally created by @OliElli on GitHub (Feb 28, 2023).

Originally assigned to: @rmanyari on GitHub.

NetBox version

v3.4.5

Feature type

Data model extension

Proposed functionality

I would like GraphQL queries to able to show the address family of an IP Address as the REST API currently does.

REST via https://netbox.acronis.work/api/ipam/ip-addresses/ endpoint:

{
  "family": {
    "value": 4,
    "label": "IPv4"
  }
}

GraphQL has no concept of the "family" field.

Per Jeremy on Slack:
Currently "family" is an attribute of the IPAddress model rather than an actual database field. The REST API serializer has an explicit field defined to convey this value whereas the GraphQL API serializer does not.

Use case

When pulling data from Netbox to configure network devices, I need to be able to distinguish between address families. I could theoretically do this in the Jinja template but I prefer to minimise data manipulation at that level.

Database changes

I believe this would require a new field.

External dependencies

No response

Originally created by @OliElli on GitHub (Feb 28, 2023). Originally assigned to: @rmanyari on GitHub. ### NetBox version v3.4.5 ### Feature type Data model extension ### Proposed functionality I would like GraphQL queries to able to show the address family of an IP Address as the REST API currently does. REST via https://netbox.acronis.work/api/ipam/ip-addresses/ endpoint: ``` { "family": { "value": 4, "label": "IPv4" } } ``` GraphQL has no concept of the "family" field. Per Jeremy on Slack: Currently "family" is an attribute of the IPAddress model rather than an actual database field. The REST API serializer has an explicit field defined to convey this value whereas the GraphQL API serializer does not. ### Use case When pulling data from Netbox to configure network devices, I need to be able to distinguish between address families. I could theoretically do this in the Jinja template but I prefer to minimise data manipulation at that level. ### Database changes I believe this would require a new field. ### External dependencies _No response_
adam added the status: acceptedtype: feature labels 2025-12-29 20:27:10 +01:00
adam closed this issue 2025-12-29 20:27:10 +01:00
Author
Owner

@rmanyari commented on GitHub (Mar 1, 2023):

Did some digging and I believe we can expose the family information without having to make DB schema changes.

We can enhance the model at the graphene level and use a custom resolver.

Here's an example (will open a PR shortly):

(netbox) rodrigo@Rodrigos-MacBook-Pro netbox % git diff
diff --git a/netbox/ipam/graphql/types.py b/netbox/ipam/graphql/types.py
index b8f6221bc..7732b78d3 100644
--- a/netbox/ipam/graphql/types.py
+++ b/netbox/ipam/graphql/types.py
@@ -64,14 +64,29 @@ class FHRPGroupAssignmentType(BaseObjectType):
         filterset_class = filtersets.FHRPGroupAssignmentFilterSet
 
 
+class IPAddressFamilyType(graphene.ObjectType):
+
+    value = graphene.Int()
+    label = graphene.String()
+
+    def __init__(self, value):
+        self.value = value
+        self.label = 'IPv4' if value == 4 else 'IPv6'
+
 class IPAddressType(NetBoxObjectType):
     assigned_object = graphene.Field('ipam.graphql.gfk_mixins.IPAddressAssignmentType')
+    family = graphene.Field(IPAddressFamilyType)
 
     class Meta:
         model = models.IPAddress
         exclude = ('assigned_object_type', 'assigned_object_id')
         filterset_class = filtersets.IPAddressFilterSet
 
+    def resolve_family(self, _):
+        # Note that self, is an instance of models.IPAddress
+        # thus resolves to the address family value.
+        return IPAddressFamilyType(self.family)
+
     def resolve_role(self, info):
         return self.role or None
 

I validated the expected behavior with:

#!/bin/bash

curl \
  --silent \
  -H "Authorization: Token $(./print-token.sh)" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  "http://localhost:${NETBOX_PORT}/graphql/" \
  --data '{"query": "query{ ip_address_list{ address, family { value, label } } }"}'

Which returns:

rodrigo@Rodrigos-MacBook-Pro scripts % ./query-ips-graphql.sh | jq .data
{
  "ip_address_list": [
    {
      "address": "192.168.1.1/32",
      "family": {
        "value": 4,
        "label": "IPv4"
      }
    },
    {
      "address": "2001:db8:3333:4444:5555:6666:7777:8888/32",
      "family": {
        "value": 6,
        "label": "IPv6"
      }
    }
  ]
}
@rmanyari commented on GitHub (Mar 1, 2023): Did some digging and I believe we can expose the family information without having to make DB schema changes. We can enhance the model at the graphene level and use a custom resolver. Here's an example (will open a PR shortly): ``` (netbox) rodrigo@Rodrigos-MacBook-Pro netbox % git diff diff --git a/netbox/ipam/graphql/types.py b/netbox/ipam/graphql/types.py index b8f6221bc..7732b78d3 100644 --- a/netbox/ipam/graphql/types.py +++ b/netbox/ipam/graphql/types.py @@ -64,14 +64,29 @@ class FHRPGroupAssignmentType(BaseObjectType): filterset_class = filtersets.FHRPGroupAssignmentFilterSet +class IPAddressFamilyType(graphene.ObjectType): + + value = graphene.Int() + label = graphene.String() + + def __init__(self, value): + self.value = value + self.label = 'IPv4' if value == 4 else 'IPv6' + class IPAddressType(NetBoxObjectType): assigned_object = graphene.Field('ipam.graphql.gfk_mixins.IPAddressAssignmentType') + family = graphene.Field(IPAddressFamilyType) class Meta: model = models.IPAddress exclude = ('assigned_object_type', 'assigned_object_id') filterset_class = filtersets.IPAddressFilterSet + def resolve_family(self, _): + # Note that self, is an instance of models.IPAddress + # thus resolves to the address family value. + return IPAddressFamilyType(self.family) + def resolve_role(self, info): return self.role or None ``` I validated the expected behavior with: ``` #!/bin/bash curl \ --silent \ -H "Authorization: Token $(./print-token.sh)" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ "http://localhost:${NETBOX_PORT}/graphql/" \ --data '{"query": "query{ ip_address_list{ address, family { value, label } } }"}' ``` Which returns: ``` rodrigo@Rodrigos-MacBook-Pro scripts % ./query-ips-graphql.sh | jq .data { "ip_address_list": [ { "address": "192.168.1.1/32", "family": { "value": 4, "label": "IPv4" } }, { "address": "2001:db8:3333:4444:5555:6666:7777:8888/32", "family": { "value": 6, "label": "IPv6" } } ] } ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#7693