Skip to content

fix: reject invalid plugin config instead of applying an empty one#441

Open
shreemaan-abhishek wants to merge 1 commit into
masterfrom
fix/plugin-config-unmarshal-fail-closed
Open

fix: reject invalid plugin config instead of applying an empty one#441
shreemaan-abhishek wants to merge 1 commit into
masterfrom
fix/plugin-config-unmarshal-fail-closed

Conversation

@shreemaan-abhishek

@shreemaan-abhishek shreemaan-abhishek commented Jul 20, 2026

Copy link
Copy Markdown

Type of change:

  • Bugfix

What this PR does / why we need it:

When a plugin's config fails to unmarshal into an object (for example a
non-object value like config: ["10.0.0.0/8"], which the CRD accepts
because config uses x-kubernetes-preserve-unknown-fields), the error
was logged and discarded, and the plugin was still applied with an empty
(or secret-only) config. So an ip-restriction plugin with a malformed
whitelist silently became ip-restriction: {} on the published route,
enforcing nothing while the resource reconciled green. The same path
serves ApisixGlobalRule, so a malformed global plugin config was
applied gateway-wide in mutated form.

This changes buildPluginConfig to return an error on a malformed
config and propagates it through every caller (route plugins,
stream-route plugins, referenced ApisixPluginConfig, ApisixGlobalRule,
Ingress plugin-config annotation, ApisixConsumer plugins). Translation
now fails instead of publishing a fabricated empty object, so the
resource keeps its last good state and the admission webhook rejects the
invalid config upfront. fillPluginFromExtensionRef, which silently
skipped such plugins, is aligned to the same fail-hard behavior.

Pre-submission checklist:

  • Did you explain what problem does this PR solve? Or what new features have been added?
  • Have you added corresponding test cases?
  • Have you modified the corresponding document?
  • Is this PR backward compatible?

Summary by CodeRabbit

  • Bug Fixes

    • Translation errors from invalid or malformed plugin configurations are now reported instead of being silently ignored.
    • Route, stream, ingress, HTTP, gRPC, consumer, and global rule processing now stops safely when plugin configuration fails.
    • Invalid plugin configuration payloads are rejected with clearer error information.
    • Secret references in valid plugin configurations continue to be handled correctly.
  • Tests

    • Added coverage for malformed configurations, invalid payloads, secret references, and error propagation across supported resource types.

A plugin config that fails to unmarshal (e.g. a non-object value) was
logged and dropped, and the plugin was still applied with an empty or
secret-only config. Translation now fails so the resource keeps its
last good state and the admission webhook rejects the change upfront.

Aligns fillPluginFromExtensionRef, which silently skipped such
plugins, to the same fail-hard behavior.
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Plugin configuration parsing now returns errors through APISIX, HTTPRoute, GRPCRoute, Ingress, and global-rule translation paths. New tests cover malformed configurations, valid secret references, and propagation behavior.

Changes

Plugin configuration error propagation

Layer / File(s) Summary
Central plugin configuration error handling
internal/adc/translator/apisixroute.go, internal/adc/translator/apisixconsumer.go, internal/adc/translator/globalrule.go
buildPluginConfig and APISIX plugin-loading callers now return configuration parsing errors.
Route extension error propagation
internal/adc/translator/httproute.go, internal/adc/translator/grpcroute.go
HTTPRoute and GRPCRoute extension-reference plugin failures now abort translation.
Ingress plugin loading propagation
internal/adc/translator/ingress.go
Ingress service and route builders now propagate stored plugin configuration errors.
Plugin configuration regression coverage
internal/adc/translator/pluginconfig_test.go
Tests cover malformed JSON, secret references, and error propagation across translation paths.

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

Suggested reviewers: alinsran


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Security Check ❌ Error Debug logs in httproute.go and ingress.go serialize plugin/config objects without redaction; those maps can contain secret-bearing plugin payloads. Remove the logs or restrict them to non-sensitive identifiers. If structured logging is needed, add redaction/MarshalLogObject for adctypes.Plugins and config structs, and never log raw plugin payloads.
E2e Test Quality Review ⚠️ Warning All added tests are unit tests against translator helpers with synthetic contexts; they don't exercise the API→reconcile→publish flow required here. Add at least one true E2E/integration test that runs the controller path and verifies malformed plugin config is rejected end-to-end; keep the unit tests too.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: malformed plugin configs are now rejected instead of silently applied.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ 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 fix/plugin-config-unmarshal-fail-closed

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
internal/adc/translator/pluginconfig_test.go (1)

39-183: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add test coverage for consumer and stream-route error propagation paths.

The test suite covers buildPlugins, buildPluginConfig, TranslateApisixGlobalRule, loadPluginConfigPluginsForIngress, and fillPluginFromExtensionRef, but two changed error-propagation paths lack regression tests:

  1. TranslateApisixConsumer (apisixconsumer.go lines 104-107): No test verifies that a malformed consumer plugin config fails consumer translation.
  2. translateStreamRule (apisixroute.go lines 491-493): No test verifies that a malformed stream-route plugin config fails stream rule translation.

Adding these tests would close the coverage gap for the fail-closed behavior this PR introduces.

🤖 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/adc/translator/pluginconfig_test.go` around lines 39 - 183, Add
regression tests for malformed plugin configurations through
TranslateApisixConsumer and translateStreamRule. Use the existing non-object
plugin config fixture, construct the required consumer and stream-route
resources and translation context, then assert translation returns an error and
no result; preserve the fail-closed assertions used by the existing buildPlugins
and global-rule tests.
🤖 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/adc/translator/pluginconfig_test.go`:
- Around line 39-183: Add regression tests for malformed plugin configurations
through TranslateApisixConsumer and translateStreamRule. Use the existing
non-object plugin config fixture, construct the required consumer and
stream-route resources and translation context, then assert translation returns
an error and no result; preserve the fail-closed assertions used by the existing
buildPlugins and global-rule tests.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d947cdf1-b6b3-4bd4-be0e-c5213d143552

📥 Commits

Reviewing files that changed from the base of the PR and between 5f84a00 and 3356e2b.

📒 Files selected for processing (7)
  • internal/adc/translator/apisixconsumer.go
  • internal/adc/translator/apisixroute.go
  • internal/adc/translator/globalrule.go
  • internal/adc/translator/grpcroute.go
  • internal/adc/translator/httproute.go
  • internal/adc/translator/ingress.go
  • internal/adc/translator/pluginconfig_test.go

@github-actions

Copy link
Copy Markdown
Contributor

conformance test report - apisix-standalone mode

apiVersion: gateway.networking.k8s.io/v1
date: "2026-07-20T11:11:02Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.3.0
implementation:
  contact: null
  organization: APISIX
  project: apisix-ingress-controller
  url: https://github.com/apache/apisix-ingress-controller.git
  version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
    result: success
    statistics:
      Failed: 0
      Passed: 12
      Skipped: 0
  name: GATEWAY-GRPC
  summary: Core tests succeeded.
- core:
    result: partial
    skippedTests:
    - HTTPRouteHTTPSListener
    statistics:
      Failed: 0
      Passed: 32
      Skipped: 1
  extended:
    result: partial
    skippedTests:
    - HTTPRouteRedirectPortAndScheme
    statistics:
      Failed: 0
      Passed: 11
      Skipped: 1
    supportedFeatures:
    - GatewayAddressEmpty
    - GatewayPort8080
    - HTTPRouteBackendProtocolWebSocket
    - HTTPRouteDestinationPortMatching
    - HTTPRouteHostRewrite
    - HTTPRouteMethodMatching
    - HTTPRoutePathRewrite
    - HTTPRoutePortRedirect
    - HTTPRouteQueryParamMatching
    - HTTPRouteRequestMirror
    - HTTPRouteResponseHeaderModification
    - HTTPRouteSchemeRedirect
    unsupportedFeatures:
    - GatewayHTTPListenerIsolation
    - GatewayInfrastructurePropagation
    - GatewayStaticAddresses
    - HTTPRouteBackendProtocolH2C
    - HTTPRouteBackendRequestHeaderModification
    - HTTPRouteBackendTimeout
    - HTTPRouteParentRefPort
    - HTTPRoutePathRedirect
    - HTTPRouteRequestMultipleMirrors
    - HTTPRouteRequestPercentageMirror
    - HTTPRouteRequestTimeout
  name: GATEWAY-HTTP
  summary: Core tests partially succeeded with 1 test skips. Extended tests partially
    succeeded with 1 test skips.
- core:
    result: partial
    skippedTests:
    - TLSRouteSimpleSameNamespace
    statistics:
      Failed: 0
      Passed: 10
      Skipped: 1
  name: GATEWAY-TLS
  summary: Core tests partially succeeded with 1 test skips.

@github-actions

Copy link
Copy Markdown
Contributor

conformance test report - apisix mode

apiVersion: gateway.networking.k8s.io/v1
date: "2026-07-20T11:12:11Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.3.0
implementation:
  contact: null
  organization: APISIX
  project: apisix-ingress-controller
  url: https://github.com/apache/apisix-ingress-controller.git
  version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
    result: success
    statistics:
      Failed: 0
      Passed: 12
      Skipped: 0
  name: GATEWAY-GRPC
  summary: Core tests succeeded.
- core:
    failedTests:
    - HTTPRouteInvalidBackendRefUnknownKind
    result: failure
    skippedTests:
    - HTTPRouteHTTPSListener
    statistics:
      Failed: 1
      Passed: 31
      Skipped: 1
  extended:
    result: partial
    skippedTests:
    - HTTPRouteRedirectPortAndScheme
    statistics:
      Failed: 0
      Passed: 11
      Skipped: 1
    supportedFeatures:
    - GatewayAddressEmpty
    - GatewayPort8080
    - HTTPRouteBackendProtocolWebSocket
    - HTTPRouteDestinationPortMatching
    - HTTPRouteHostRewrite
    - HTTPRouteMethodMatching
    - HTTPRoutePathRewrite
    - HTTPRoutePortRedirect
    - HTTPRouteQueryParamMatching
    - HTTPRouteRequestMirror
    - HTTPRouteResponseHeaderModification
    - HTTPRouteSchemeRedirect
    unsupportedFeatures:
    - GatewayHTTPListenerIsolation
    - GatewayInfrastructurePropagation
    - GatewayStaticAddresses
    - HTTPRouteBackendProtocolH2C
    - HTTPRouteBackendRequestHeaderModification
    - HTTPRouteBackendTimeout
    - HTTPRouteParentRefPort
    - HTTPRoutePathRedirect
    - HTTPRouteRequestMultipleMirrors
    - HTTPRouteRequestPercentageMirror
    - HTTPRouteRequestTimeout
  name: GATEWAY-HTTP
  summary: Core tests failed with 1 test failures. Extended tests partially succeeded
    with 1 test skips.
- core:
    result: partial
    skippedTests:
    - TLSRouteSimpleSameNamespace
    statistics:
      Failed: 0
      Passed: 10
      Skipped: 1
  name: GATEWAY-TLS
  summary: Core tests partially succeeded with 1 test skips.

@github-actions

Copy link
Copy Markdown
Contributor

conformance test report

apiVersion: gateway.networking.k8s.io/v1
date: "2026-07-20T11:29:03Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.3.0
implementation:
  contact: null
  organization: APISIX
  project: apisix-ingress-controller
  url: https://github.com/apache/apisix-ingress-controller.git
  version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
    failedTests:
    - GatewayModifyListeners
    result: failure
    statistics:
      Failed: 1
      Passed: 11
      Skipped: 0
  name: GATEWAY-GRPC
  summary: Core tests failed with 1 test failures.
- core:
    failedTests:
    - GatewayModifyListeners
    result: failure
    skippedTests:
    - HTTPRouteHTTPSListener
    statistics:
      Failed: 1
      Passed: 31
      Skipped: 1
  extended:
    result: partial
    skippedTests:
    - HTTPRouteRedirectPortAndScheme
    statistics:
      Failed: 0
      Passed: 11
      Skipped: 1
    supportedFeatures:
    - GatewayAddressEmpty
    - GatewayPort8080
    - HTTPRouteBackendProtocolWebSocket
    - HTTPRouteDestinationPortMatching
    - HTTPRouteHostRewrite
    - HTTPRouteMethodMatching
    - HTTPRoutePathRewrite
    - HTTPRoutePortRedirect
    - HTTPRouteQueryParamMatching
    - HTTPRouteRequestMirror
    - HTTPRouteResponseHeaderModification
    - HTTPRouteSchemeRedirect
    unsupportedFeatures:
    - GatewayHTTPListenerIsolation
    - GatewayInfrastructurePropagation
    - GatewayStaticAddresses
    - HTTPRouteBackendProtocolH2C
    - HTTPRouteBackendRequestHeaderModification
    - HTTPRouteBackendTimeout
    - HTTPRouteParentRefPort
    - HTTPRoutePathRedirect
    - HTTPRouteRequestMultipleMirrors
    - HTTPRouteRequestPercentageMirror
    - HTTPRouteRequestTimeout
  name: GATEWAY-HTTP
  summary: Core tests failed with 1 test failures. Extended tests partially succeeded
    with 1 test skips.
- core:
    failedTests:
    - GatewayModifyListeners
    - TLSRouteSimpleSameNamespace
    result: failure
    statistics:
      Failed: 2
      Passed: 9
      Skipped: 0
  name: GATEWAY-TLS
  summary: Core tests failed with 2 test failures.

@shreemaan-abhishek shreemaan-abhishek self-assigned this Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant