Skip to content

Extend NetworkInterface status with firmware version and other details#983

Open
afritzler wants to merge 3 commits into
mainfrom
enh/nic-info
Open

Extend NetworkInterface status with firmware version and other details#983
afritzler wants to merge 3 commits into
mainfrom
enh/nic-info

Conversation

@afritzler

@afritzler afritzler commented Jul 3, 2026

Copy link
Copy Markdown
Member

Proposed Changes

Extend NetworkInterface status with firmware vesion and other details.

Fixes #981

Summary by CodeRabbit

  • New Features
    • Network interface details now include PCI address, speed, link modes, supported ports, and firmware version.
    • Server API responses and CRD status network interface fields were extended with these additional NIC metadata.
  • Bug Fixes
    • Server network interface assembly is now more complete, merging registry data with probe hardware attributes and LLDP neighbors more reliably.
  • Documentation
    • Updated the API reference to display the new network interface fields.
  • Tests
    • Improved the “server from Endpoint” test to validate the full expected NIC details.

@afritzler afritzler requested a review from a team as a code owner July 3, 2026 10:47
@github-actions github-actions Bot added size/L api-change documentation Improvements or additions to documentation enhancement New feature or request labels Jul 3, 2026
@afritzler afritzler changed the title Extend NetworkInterface status with firmware vesion and other details Extend NetworkInterface status with firmware version and other details Jul 3, 2026
Signed-off-by: Andreas Fritzler <andreas.fritzler@sap.com>
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds new NIC hardware metadata fields across the NetworkInterface API, generated applyconfiguration and schema code, CRD/docs, registry and probe data, and server controller logic that merges registry-reported NIC and LLDP details into server status.

Changes

NIC hardware detail fields

Layer / File(s) Summary
NetworkInterface type and generated code
api/v1alpha1/server_types.go, api/v1alpha1/applyconfiguration/api/v1alpha1/networkinterface.go, api/v1alpha1/applyconfiguration/internal/internal.go, api/v1alpha1/zz_generated.deepcopy.go, internal/api/registry/nic.go, internal/probe/nics_linux.go, internal/probe/nics_darwin.go
Adds the new NIC metadata fields to the API and generated configuration/schema code, expands the registry NIC model, and populates the extra fields from Linux and Darwin probe collection.
CRD schema and API docs updates
config/crd/bases/metal.ironcore.dev_servers.yaml, docs/api-reference/api.md
Extends the Server CRD schema and API reference table with the new per-interface NIC properties.
Controller NIC merge logic
internal/controller/server_controller.go, internal/controller/server_controller_test.go
Refactors network interface construction into a helper that merges registry NIC hardware and LLDP data into server status, and updates the controller test to POST registration data and assert the full resulting interface set.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR adds several NIC metadata fields, but the linked issue also asks for ethtool channel and driver info that are not shown in the reviewed changes. Add the missing ethtool driverInfo and full channels fields to NetworkInterface status, and wire them through probe/controller code.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change by describing the NetworkInterface status extension with firmware and related NIC details.
Description check ✅ Passed The description follows the template's Proposed Changes and Fixes sections and clearly states the feature and linked issue.
Out of Scope Changes check ✅ Passed The codegen, docs, tests, and controller updates all support the NetworkInterface status expansion and do not appear unrelated.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch enh/nic-info

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.

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

🧹 Nitpick comments (2)
api/v1alpha1/server_types.go (1)

336-338: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider a more structured type for Speed.

Speed is a free-form string (e.g. registry sends "10000"), which loses unit semantics and can't be validated/sorted/compared like a numeric quantity. Since this is new API surface, using an integer (Mbps) or resource.Quantity would be more idiomatic and future-proof, though string is workable if the Redfish/ethtool source data itself is inconsistent in units.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api/v1alpha1/server_types.go` around lines 336 - 338, The Speed field on the
server status type is currently a free-form string, which makes it hard to
validate and compare consistently. Update the Server type’s Speed field in the
server_types definition to use a more structured representation such as an
integer in Mbps or resource.Quantity, and adjust any related JSON/schema
handling and consumers of Speed so the API surface stays future-proof and
semantically clear.
internal/controller/server_controller.go (1)

1028-1052: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider covering the MAC-fallback match path with a unit test.

The merge logic here has three distinct branches (name match, MAC-fallback match, no match), but the added integration test in server_controller_test.go only exercises the name-match path (NIC name equals interface name). Since buildNetworkInterfaces is a standalone, easily-testable function, a small table-driven unit test covering the MAC-fallback and no-match cases would guard against regressions in this non-trivial matching logic.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/controller/server_controller.go` around lines 1028 - 1052, Add a
focused table-driven unit test for buildNetworkInterfaces that covers the MAC
fallback and no-match branches in the NIC merge logic. Use the existing
name-match test as a reference, then create cases where registryNICs matches a
NIC by MACAddress only and where no registry NIC matches at all; assert that
hardware fields are merged in the fallback case and remain unchanged in the
no-match case. This should exercise the nicsByMAC lookup and the loop over nics
so the matching behavior is protected from regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@api/v1alpha1/server_types.go`:
- Around line 336-338: The Speed field on the server status type is currently a
free-form string, which makes it hard to validate and compare consistently.
Update the Server type’s Speed field in the server_types definition to use a
more structured representation such as an integer in Mbps or resource.Quantity,
and adjust any related JSON/schema handling and consumers of Speed so the API
surface stays future-proof and semantically clear.

In `@internal/controller/server_controller.go`:
- Around line 1028-1052: Add a focused table-driven unit test for
buildNetworkInterfaces that covers the MAC fallback and no-match branches in the
NIC merge logic. Use the existing name-match test as a reference, then create
cases where registryNICs matches a NIC by MACAddress only and where no registry
NIC matches at all; assert that hardware fields are merged in the fallback case
and remain unchanged in the no-match case. This should exercise the nicsByMAC
lookup and the loop over nics so the matching behavior is protected from
regressions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2edf0503-5186-4ed4-b0c4-6e130e19bf7a

📥 Commits

Reviewing files that changed from the base of the PR and between 6329651 and 0c0832e.

⛔ Files ignored due to path filters (1)
  • dist/chart/templates/crd/metal.ironcore.dev_servers.yaml is excluded by !**/dist/**
📒 Files selected for processing (8)
  • api/v1alpha1/applyconfiguration/api/v1alpha1/networkinterface.go
  • api/v1alpha1/applyconfiguration/internal/internal.go
  • api/v1alpha1/server_types.go
  • api/v1alpha1/zz_generated.deepcopy.go
  • config/crd/bases/metal.ironcore.dev_servers.yaml
  • docs/api-reference/api.md
  • internal/controller/server_controller.go
  • internal/controller/server_controller_test.go

Signed-off-by: Andreas Fritzler <andreas.fritzler@sap.com>

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

works in vm devenv, there just is no channel information in a qemu vm when using the jaypipes/ethtool:

kubectl get servers -o yaml
...
    networkInterfaces:
    - carrierStatus: up
      device: "0x0001"
      ips:
      - 172.19.100.3
      - fe80::5054:ff:fede:5965
      macAddress: 52:54:00:de:59:65
      name: enp0s2
      pciAddress: unknown
      speed: "-1"
      vendor: "0x1af4"

@afritzler

Copy link
Copy Markdown
Member Author

works in vm devenv, there just is no channel information in a qemu vm when using the jaypipes/ethtool:

kubectl get servers -o yaml
...
    networkInterfaces:
    - carrierStatus: up
      device: "0x0001"
      ips:
      - 172.19.100.3
      - fe80::5054:ff:fede:5965
      macAddress: 52:54:00:de:59:65
      name: enp0s2
      pciAddress: unknown
      speed: "-1"
      vendor: "0x1af4"

No FirmwareVersion?

Signed-off-by: Andreas Fritzler <andreas.fritzler@sap.com>
@github-actions github-actions Bot added size/XL and removed size/L labels Jul 3, 2026

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

🧹 Nitpick comments (2)
internal/probe/nics_linux.go (1)

64-69: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Silent swallow of GetChannels errors.

Channel-capacity errors are dropped without logging, so real failures (e.g. driver doesn't support ethtool -g, or a permission issue) are indistinguishable from the field being legitimately absent. Given the PR's intent ("optional sysfs-based details when available"), this is acceptable behavior-wise, but consider a debug-level log for observability.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/probe/nics_linux.go` around lines 64 - 69, The GetChannels call in
probeNICs silently ignores errors, making real failures indistinguishable from
missing data. Update the nics_linux.go logic around ethHandle.GetChannels in the
NIC probe path to keep the optional behavior but add a debug-level log when the
call fails, including the NIC name and the error. Use the existing probe flow in
the NIC collection code so observability improves without changing the fallback
behavior.
internal/controller/server_controller.go (1)

1052-1052: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Unchecked narrowing conversions can wrap hardware counters into corrupted status values.

hw.NUMANode (int) and hw.MaxRx/MaxTx/MaxOther/MaxCombined (uint32) are cast directly to int32 with no bounds check. If a device ever reports a queue count above math.MaxInt32, the resulting persisted status field silently wraps to a negative number, corrupting the CR status without any error surfaced.

🛡️ Proposed fix: clamp before narrowing
+func clampToInt32(v uint32) int32 {
+	if v > math.MaxInt32 {
+		return math.MaxInt32
+	}
+	return int32(v)
+}
+
 		nics[i].PCIAddress = hw.PCIAddress
 		nics[i].Speed = hw.Speed
 		nics[i].LinkModes = hw.LinkModes
 		nics[i].SupportedPorts = hw.SupportedPorts
 		nics[i].FirmwareVersion = hw.FirmwareVersion
 		nics[i].NUMANode = int32(hw.NUMANode)
 		nics[i].Vendor = hw.Vendor
 		nics[i].SubsystemVendor = hw.SubsystemVendor
 		nics[i].Device = hw.Device
-		nics[i].MaxRx = int32(hw.MaxRx)
-		nics[i].MaxTx = int32(hw.MaxTx)
-		nics[i].MaxOther = int32(hw.MaxOther)
-		nics[i].MaxCombined = int32(hw.MaxCombined)
+		nics[i].MaxRx = clampToInt32(hw.MaxRx)
+		nics[i].MaxTx = clampToInt32(hw.MaxTx)
+		nics[i].MaxOther = clampToInt32(hw.MaxOther)
+		nics[i].MaxCombined = clampToInt32(hw.MaxCombined)

Practically, real-world channel/queue counts stay well below this bound, but the fix is cheap and removes the CWE-190 risk flagged by static analysis.

Also applies to: 1056-1059

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/controller/server_controller.go` at line 1052, The status population
in server_controller’s NIC handling is doing unchecked narrowing from
hw.NUMANode and hw.MaxRx/MaxTx/MaxOther/MaxCombined into int32 fields, which can
silently wrap large hardware values. Update the NIC status assignment logic
around the nics slice population to clamp or validate these hardware counters
before casting, and only persist bounded values into the CR status. Use the
existing NIC-building loop and the NUMANode/MaxRx/MaxTx/MaxOther/MaxCombined
assignments as the focal points for the fix.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@internal/controller/server_controller.go`:
- Line 1052: The status population in server_controller’s NIC handling is doing
unchecked narrowing from hw.NUMANode and hw.MaxRx/MaxTx/MaxOther/MaxCombined
into int32 fields, which can silently wrap large hardware values. Update the NIC
status assignment logic around the nics slice population to clamp or validate
these hardware counters before casting, and only persist bounded values into the
CR status. Use the existing NIC-building loop and the
NUMANode/MaxRx/MaxTx/MaxOther/MaxCombined assignments as the focal points for
the fix.

In `@internal/probe/nics_linux.go`:
- Around line 64-69: The GetChannels call in probeNICs silently ignores errors,
making real failures indistinguishable from missing data. Update the
nics_linux.go logic around ethHandle.GetChannels in the NIC probe path to keep
the optional behavior but add a debug-level log when the call fails, including
the NIC name and the error. Use the existing probe flow in the NIC collection
code so observability improves without changing the fallback behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7b1513e7-7afd-42e4-b4c0-9d14b54f1238

📥 Commits

Reviewing files that changed from the base of the PR and between 0c0832e and 22d65d2.

⛔ Files ignored due to path filters (1)
  • dist/chart/templates/crd/metal.ironcore.dev_servers.yaml is excluded by !**/dist/**
📒 Files selected for processing (11)
  • api/v1alpha1/applyconfiguration/api/v1alpha1/networkinterface.go
  • api/v1alpha1/applyconfiguration/internal/internal.go
  • api/v1alpha1/server_types.go
  • api/v1alpha1/zz_generated.deepcopy.go
  • config/crd/bases/metal.ironcore.dev_servers.yaml
  • docs/api-reference/api.md
  • internal/api/registry/nic.go
  • internal/controller/server_controller.go
  • internal/controller/server_controller_test.go
  • internal/probe/nics_darwin.go
  • internal/probe/nics_linux.go
✅ Files skipped from review due to trivial changes (3)
  • docs/api-reference/api.md
  • api/v1alpha1/applyconfiguration/api/v1alpha1/networkinterface.go
  • api/v1alpha1/applyconfiguration/internal/internal.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • config/crd/bases/metal.ironcore.dev_servers.yaml
  • api/v1alpha1/zz_generated.deepcopy.go
  • api/v1alpha1/server_types.go
  • internal/controller/server_controller_test.go

@afritzler afritzler requested a review from xkonni July 9, 2026 12:34
@afritzler afritzler added the minor label Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api-change documentation Improvements or additions to documentation enhancement New feature or request minor size/XL

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Enhance visibility of network interface cards during probing

2 participants