Skip to content

Add internal/apistatus package with typed terminal errors#325

Open
felix-kaestner wants to merge 4 commits intomainfrom
feat/unsupported-fields
Open

Add internal/apistatus package with typed terminal errors#325
felix-kaestner wants to merge 4 commits intomainfrom
feat/unsupported-fields

Conversation

@felix-kaestner
Copy link
Copy Markdown
Contributor

@felix-kaestner felix-kaestner commented Apr 27, 2026

Introduces internal/apistatus, a package that gives provider implementations a structured way to return non-retryable errors to controllers without coupling directly to reconcile.TerminalError.

The package defines a Code enum (CodeInvalidArgument, CodeUnsupportedField, CodeFailedPrecondition) with String() and Valid() methods, a StatusError struct carrying a Code, an optional Message, and optional FieldViolations, and constructor functions for each code. StatusError implements Is() so that errors.Is can be used for type detection across error chains. WrapTerminalError wraps any error containing a *StatusError as a reconcile.TerminalError, leaving all other errors unchanged.

conditions.FromError is extended to detect *StatusError before the existing gRPC status path, mapping the code to the condition Reason and the formatted message to the condition Message field.

The stub internal/controllerutil package, which this supersedes, has been removed as no code imported it.

@felix-kaestner felix-kaestner requested a review from a team as a code owner April 27, 2026 07:57
@felix-kaestner felix-kaestner changed the title Add internal/apistatus package with typed terminal errors Add internal/apistatus package with typed terminal errors Apr 27, 2026
@hardikdr hardikdr added the area/switch-automation Automation processes for network switch management and operations. label Apr 28, 2026
@hardikdr hardikdr added this to Roadmap Apr 28, 2026
@felix-kaestner felix-kaestner force-pushed the feat/unsupported-fields branch from f21b349 to 8f3ca56 Compare May 4, 2026 08:41
Introduces internal/apistatus, a leaf package that gives provider
implementations a structured way to return non-retryable errors to
controllers without coupling directly to reconcile.TerminalError.

The package defines a Code enum (CodeInvalidArgument, CodeUnsupportedField,
CodeFailedPrecondition) with String() and Valid() methods, a StatusError
struct carrying a Code, an optional Message, and optional FieldViolations,
and constructor functions for each code. StatusError implements Is() so
that errors.Is can be used for type detection across error chains.
WrapTerminalError wraps any error containing a *StatusError as a
reconcile.TerminalError, leaving all other errors unchanged.

conditions.FromError is extended to detect *StatusError before the
existing gRPC status path, mapping the code to the condition Reason
and the formatted message to the condition Message field.

The stub internal/controllerutil package, which this supersedes, has
been removed as no code imported it.
Each controller's Reconcile method now passes provider errors through
apistatus.WrapTerminalError before returning them to controller-runtime.

This ensures that any *StatusError returned by a provider implementation
— signalling an unsupported field, an invalid argument, or an unmet
precondition — suppresses retry backoff and is treated as a terminal
error by the reconciler. Transient errors and Kubernetes-level
precondition failures are returned unchanged, preserving existing
retry behaviour for those cases.
Replace plain fmt.Errorf/errors.New calls in the NX-OS provider and
name.go with typed apistatus errors so non-retryable failures surface
as structured Kubernetes status conditions with a stable Reason field.
WrapTerminalError now only promotes CodeInvalidArgument and
CodeUnsupportedField to reconcile.TerminalError. CodeFailedPrecondition
errors pass through unchanged so controller-runtime exponential backoff
can requeue them — the precondition (e.g. a BGP process) may become
true on a future attempt.

Update docs and tests to reflect the new behaviour.
@felix-kaestner felix-kaestner force-pushed the feat/unsupported-fields branch from 8f3ca56 to d9139f1 Compare May 5, 2026 19:20
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

Merging this branch changes the coverage (2 decrease, 2 increase)

Impacted Packages Coverage Δ 🤖
github.com/ironcore-dev/network-operator/internal/apistatus 96.30% (+96.30%) 🌟
github.com/ironcore-dev/network-operator/internal/conditions 75.38% (-4.94%) 👎
github.com/ironcore-dev/network-operator/internal/controller/cisco/nx 65.05% (-0.18%) 👎
github.com/ironcore-dev/network-operator/internal/controller/core 63.00% (+0.08%) 👍
github.com/ironcore-dev/network-operator/internal/provider/cisco/nxos 9.94% (ø)

Coverage by file

Changed files (no unit tests)

Changed File Coverage Δ Total Covered Missed 🤖
github.com/ironcore-dev/network-operator/internal/apistatus/apistatus.go 96.30% (+96.30%) 27 (+27) 26 (+26) 1 (+1) 🌟
github.com/ironcore-dev/network-operator/internal/conditions/conditions.go 75.38% (-4.94%) 65 (+4) 49 16 (+4) 👎
github.com/ironcore-dev/network-operator/internal/controller/cisco/nx/bordergateway_controller.go 52.97% (ø) 236 125 111
github.com/ironcore-dev/network-operator/internal/controller/cisco/nx/system_controller.go 65.52% (ø) 116 76 40
github.com/ironcore-dev/network-operator/internal/controller/cisco/nx/vpcdomain_controller.go 78.64% (-0.49%) 206 162 (-1) 44 (+1) 👎
github.com/ironcore-dev/network-operator/internal/controller/core/acl_controller.go 58.16% (ø) 141 82 59
github.com/ironcore-dev/network-operator/internal/controller/core/banner_controller.go 57.99% (ø) 169 98 71
github.com/ironcore-dev/network-operator/internal/controller/core/bgp_controller.go 68.53% (-0.86%) 232 159 (-2) 73 (+2) 👎
github.com/ironcore-dev/network-operator/internal/controller/core/bgp_peer_controller.go 58.28% (+1.27%) 314 183 (+4) 131 (-4) 👍
github.com/ironcore-dev/network-operator/internal/controller/core/certificate_controller.go 58.71% (ø) 155 91 64
github.com/ironcore-dev/network-operator/internal/controller/core/dhcprelay_controller.go 65.89% (ø) 258 170 88
github.com/ironcore-dev/network-operator/internal/controller/core/dns_controller.go 57.97% (ø) 138 80 58
github.com/ironcore-dev/network-operator/internal/controller/core/evpninstance_controller.go 68.75% (+0.48%) 208 143 (+1) 65 (-1) 👍
github.com/ironcore-dev/network-operator/internal/controller/core/interface_controller.go 65.70% (-0.36%) 551 362 (-2) 189 (+2) 👎
github.com/ironcore-dev/network-operator/internal/controller/core/isis_controller.go 60.12% (ø) 173 104 69
github.com/ironcore-dev/network-operator/internal/controller/core/lldp_controller.go 69.59% (ø) 217 151 66
github.com/ironcore-dev/network-operator/internal/controller/core/managementaccess_controller.go 57.97% (ø) 138 80 58
github.com/ironcore-dev/network-operator/internal/controller/core/ntp_controller.go 57.97% (ø) 138 80 58
github.com/ironcore-dev/network-operator/internal/controller/core/nve_controller.go 68.98% (+0.46%) 216 149 (+1) 67 (-1) 👍
github.com/ironcore-dev/network-operator/internal/controller/core/ospf_controller.go 59.80% (ø) 204 122 82
github.com/ironcore-dev/network-operator/internal/controller/core/pim_controller.go 61.27% (+1.16%) 173 106 (+2) 67 (-2) 👍
github.com/ironcore-dev/network-operator/internal/controller/core/prefixset_controller.go 61.70% (ø) 141 87 54
github.com/ironcore-dev/network-operator/internal/controller/core/routingpolicy_controller.go 67.54% (ø) 191 129 62
github.com/ironcore-dev/network-operator/internal/controller/core/snmp_controller.go 57.97% (ø) 138 80 58
github.com/ironcore-dev/network-operator/internal/controller/core/syslog_controller.go 58.16% (ø) 141 82 59
github.com/ironcore-dev/network-operator/internal/controller/core/user_controller.go 56.80% (ø) 169 96 73
github.com/ironcore-dev/network-operator/internal/controller/core/vlan_controller.go 62.00% (ø) 150 93 57
github.com/ironcore-dev/network-operator/internal/controller/core/vrf_controller.go 62.32% (ø) 138 86 52
github.com/ironcore-dev/network-operator/internal/provider/cisco/nxos/name.go 61.54% (ø) 26 16 10
github.com/ironcore-dev/network-operator/internal/provider/cisco/nxos/provider.go 0.06% (ø) 1779 1 1778

Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code.

Changed unit test files

  • github.com/ironcore-dev/network-operator/internal/apistatus/apistatus_test.go

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

Labels

area/switch-automation Automation processes for network switch management and operations. size/L

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants