netbox-community / netbox

The premier source of truth powering network automation. Open source under Apache 2. Try NetBox Cloud free: https://netboxlabs.com/free-netbox-cloud/
http://netboxlabs.com/oss/netbox/
Apache License 2.0
16.3k stars 2.59k forks source link

GraphQL API Improperly formatting choice fields #14494

Closed tyler-8 closed 7 months ago

tyler-8 commented 11 months ago

Deployment Type

Self-hosted

NetBox Version

v3.6.6 v3.3.10

Python Version

3.10

Steps to Reproduce

  1. Create a Device (Router1), using an arbitrary site (australia in this example) & device type
  2. Create an Interface Gig1 on Router1 with a type of 1000base-x-sfp
  3. Using the GraphQL API, run this query
    query {
    device_list(site:"australia", name: "Router1") {
    name
    site {
      name
      status
    }
    status
    interfaces {
      name
      type
      enabled
    }
    }
    }

Expected Behavior

Expected output:

{
  "data": {
    "device_list": [
      {
        "name": "Router1",
        "site": {
          "name": "Australia",
          "status": "active"  // site status value is lowercase to match raw value
        },
        "status": "active",  // device status value is lowercase to match raw value
        "interfaces": [
          {
            "name": "Gig1",
            "type": "1000base-x-sfp",  // interface type matches value & casing of raw value
            "enabled": true
          }
        ]
      }
    ]
  }
}

Observed Behavior

{
  "data": {
    "device_list": [
      {
        "name": "Router1",
        "site": {
          "name": "Australia",
          "status": "ACTIVE"  // site status is uppercase
        },
        "status": "ACTIVE",  // device status is uppercase
        "interfaces": [
          {
            "name": "Gig1",
            "type": "A_1000BASE_X_SFP",  // interface type value as "A_" prepended, hyphens are now underscores, and all uppercase.
            "enabled": true
          }
        ]
      }
    ]
  }
}

Status & type field have incorrect formatting and values. This makes it more involved to clean up the data to match back to NetBox itself. For example, when reading data with GraphQL and writing data with REST.

I think any interface type value that starts with a number is getting "A_" prepended.

A_40GBASE_X_QSFPP

Example output for type field using a wireless type and another non-numeric-starting value:

IEEE802_11AD INFINIBAND_XDR

tyler-8 commented 11 months ago

It appears this is a behavior of graphene-Django and it can be disabled.

https://docs.graphene-python.org/projects/django/en/latest/queries/#choices-to-enum-conversion

IMO it should be since this essentially causes the GraphQL API to return "invalid" data values.

More detail from old issue on the graphene-django repo: https://github.com/graphql-python/graphene-django/issues/67

tyler-8 commented 11 months ago

Here's an example of how this would be fixed using the option documented in my previous post:

class InterfaceType(IPAddressesMixin, ComponentObjectType, CabledObjectMixin, PathEndpointMixin):

    class Meta:
        model = models.Interface
        exclude = ('_path',)
        filterset_class = filtersets.InterfaceFilterSet
        convert_choices_to_enum = False  # Setting to disable Enum conversion

    def resolve_poe_mode(self, info):
        return self.poe_mode or None

    def resolve_poe_type(self, info):
        return self.poe_type or None

    def resolve_mode(self, info):
        return self.mode or None

    def resolve_rf_role(self, info):
        return self.rf_role or None

    def resolve_rf_channel(self, info):
        return self.rf_channel or None
github-actions[bot] commented 7 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. Do not attempt to circumvent this process by "bumping" the issue; doing so will result in its immediate closure and you may be barred from participating in any future discussions. Please see our contributing guide.

tyler-8 commented 7 months ago

Since GitHub reminded me about this; and just an FYI for any future users coming across this issue:

It's no longer relevant given the migration to Strawberry that's coming in NetBox 4.0.