Conversation
There was a problem hiding this comment.
Pull request overview
Adds support for Event Gateway Virtual Cluster Produce Policies across kongctl’s declarative engine, imperative get, and dump flows (view/UI skipped for now), aligning with Konnect Event Gateway v1 APIs.
Changes:
- Introduces a new declarative resource type for virtual-cluster produce policies (nested + root-level) with planner + executor support.
- Adds imperative
get event-gateway virtual-cluster produce-policiescommand (including interactive child loading) and dump support that preserves full policyconfigvia raw-response parsing. - Extends E2E plan/apply/sync workflows to cover create/update/delete and root-level declaration scenarios.
Reviewed changes
Copilot reviewed 33 out of 33 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test/e2e/scenarios/event-gateway/produce-policy/testdata/config.yaml | Base E2E declarative config including nested produce_policies. |
| test/e2e/scenarios/event-gateway/produce-policy/scenario.yaml | Comprehensive E2E scenario for apply/update/sync-delete + root-level declaration. |
| test/e2e/scenarios/event-gateway/produce-policy/overlays/001-update-fields/config.yaml | Overlay updating produce-policy fields for update coverage. |
| test/e2e/scenarios/event-gateway/produce-policy/overlays/002-sync-delete/config.yaml | Overlay removing nested produce policies for sync-delete coverage. |
| test/e2e/scenarios/event-gateway/produce-policy/overlays/003-root-level-declaration/config.yaml | Overlay declaring produce policies at root level. |
| test/e2e/scenarios/event-gateway/produce-policy/overlays/004-sync-delete-root-level-declaration/config.yaml | Overlay clearing root-level produce policies for sync-delete coverage. |
| test/e2e/scenarios/event-gateway/plan/sync-workflow/scenario.yaml | Adds plan+sync workflow coverage for produce policies. |
| test/e2e/scenarios/event-gateway/plan/sync-workflow/overlays/008-produce-policy/config.yaml | Adds sync overlay config containing a nested produce policy. |
| test/e2e/scenarios/event-gateway/plan/apply-workflow/scenario.yaml | Adds plan+apply workflow coverage for produce policies. |
| test/e2e/scenarios/event-gateway/plan/apply-workflow/overlays/008-produce-policy/config.yaml | Adds apply overlay config containing a nested produce policy. |
| internal/processes/runtime.go | Moves runtime default constants into runtime implementation file. |
| internal/processes/runtime_types.go | Removes duplicated runtime default constants. |
| internal/konnect/helpers/sdk.go | Extends SDKAPI with GetEventGatewayProducePolicyAPI. |
| internal/konnect/helpers/sdk_mock.go | Adds mock factory + getter for produce policy API. |
| internal/konnect/helpers/event_gateway_produce_policies.go | Adds helper interface/impl wrapper around SDK produce policy endpoints. |
| internal/declarative/state/client.go | Adds state-client CRUD/list/get for virtual-cluster produce policies (including raw config extraction). |
| internal/declarative/resources/types.go | Adds resource type constant + ResourceSet aggregation helper for produce policies. |
| internal/declarative/resources/event_gateway_virtual_cluster.go | Supports nested produce_policies under virtual clusters (validate/defaults/json). |
| internal/declarative/resources/event_gateway_produce_policy.go | Introduces declarative produce policy resource (union handling + JSON marshal/unmarshal). |
| internal/declarative/protection/lookup.go | Marks new produce policy type as not protected by managed-resource protection rules. |
| internal/declarative/planner/event_gateway_virtual_cluster_planner.go | Hooks produce policy planning into virtual cluster create/update planning. |
| internal/declarative/planner/event_gateway_produce_policy_planner.go | Implements produce policy planner logic (create/update/delete + config diff). |
| internal/declarative/planner/event_gateway_produce_policy_planner_test.go | Unit tests for produce policy update detection logic. |
| internal/declarative/planner/constants.go | Adds FieldCurrentConfig constant and new resource type constant. |
| internal/declarative/executor/executor.go | Wires produce policy executor into apply/sync execution paths. |
| internal/declarative/executor/event_gateway_produce_policy_adapter.go | Adapter for mapping planned changes to SDK produce policy CRUD calls. |
| internal/cmd/root/verbs/dump/declarative.go | Injects produce policy API into dump’s state client. |
| internal/cmd/root/verbs/dump/declarative_children.go | Dumps nested produce policies under virtual clusters with full raw config. |
| internal/cmd/root/products/konnect/eventgateway/virtual_clusters.go | Adds produce-policies as a child subcommand under virtual clusters. |
| internal/cmd/root/products/konnect/eventgateway/produce-policies.go | Implements imperative get ... produce-policies command + raw-config output handling. |
| internal/cmd/root/products/konnect/eventgateway/produce-policies_test.go | Adds tests for flag validation + helper functions for the new command. |
| internal/cmd/root/products/konnect/eventgateway/interactive_children.go | Adds interactive child loader for virtual-cluster produce policies. |
| internal/cmd/root/products/konnect/declarative/declarative.go | Injects produce policy API into declarative state client creation. |
internal/cmd/root/products/konnect/eventgateway/produce-policies.go
Outdated
Show resolved
Hide resolved
040e72a to
7aaf4e8
Compare
|
Rebased with main and verified that |
| } else if len(current.Labels) > 0 { | ||
| needsUpdate = true | ||
| changes["labels"] = FieldChange{Old: current.Labels, New: map[string]string{}} | ||
| } |
There was a problem hiding this comment.
When desired labels are omitted (desiredLabels == nil) but the current policy has labels, this code flags an update to remove labels, but the planned update payload is built via producePolicyToFields(desired) and won’t include a "labels" field. Since the executor/adapter doesn’t apply FieldCurrentLabels to construct a label update, this won’t actually clear labels. Consider either treating omitted labels as “leave unchanged”, or explicitly setting updateFields["labels"] to an empty map when planning label removal (and/or implement executor-side label removal using FieldCurrentLabels).
| var updateFields map[string]any | ||
| if needsUpdate { | ||
| updateFields = p.producePolicyToFields(desired) | ||
| updateFields[FieldCurrentConfig] = current.RawConfig |
There was a problem hiding this comment.
FieldCurrentConfig is added into updateFields, but there is no executor/adapter logic that reads _current_config (unlike _current_labels). This makes the field ineffective at best and can leak internal metadata into the SDK union unmarshaling payload. Either remove _current_config entirely or implement the intended merge/removal behavior in the executor/adapter and strip the internal field before marshaling the SDK request.
| updateFields[FieldCurrentConfig] = current.RawConfig |
| func (p *Planner) shouldUpdateProducePolicy( | ||
| current state.EventGatewayVirtualClusterProducePolicyInfo, | ||
| desired resources.EventGatewayProducePolicyResource, | ||
| ) (bool, map[string]any, map[string]FieldChange) { | ||
| var needsUpdate bool | ||
| changes := make(map[string]FieldChange) |
There was a problem hiding this comment.
shouldUpdateProducePolicy never compares the current policy Type to the desired policy type (derived from which union variant is set). A type-only change (or a change masked by missing/empty RawConfig) can be missed, and if type changes are not supported by the API, the planner should force a recreate instead of an update. Consider adding an explicit type comparison and handling (UPDATE vs DELETE+CREATE) accordingly.
| policyMap := map[string]any{ | ||
| "type": policy.Type, | ||
| "config": rawConfig, | ||
| } | ||
| if policy.Name != nil { |
There was a problem hiding this comment.
Dump conversion for produce policies currently only maps type/name/description/enabled/labels/config. If the API returns fields like condition and parent_policy_id (similar to cluster policies), they’ll be dropped from the dumped declarative config and won’t round-trip. Consider including these fields in policyMap when present, mirroring convertClusterPolicyToResource.
| # event_gateway_produce_policies removed for sync delete test | ||
| event_gateway_virtual_cluster_produce_policies: [] No newline at end of file |
There was a problem hiding this comment.
The comment mentions event_gateway_produce_policies, but the actual root-level key used in this scenario is event_gateway_virtual_cluster_produce_policies (as also noted in the PR description). Updating the comment will avoid confusion when maintaining these overlays.
Summary
In this PR, we are adding support for Event Gateway Virtual Cluster Produce Policy -
Note:
Resource key is
produce_policieswhen nested undervirtual_clusters, andevent_gateway_virtual_cluster_produce_policieswhen declared at root level.Example for imperative Get:
Full changelog
Implement https://github.com/Kong/kongctl/issues/214
Testing