From c3a2bd9fe2a87bd0e2305393a7b62863a5d67b34 Mon Sep 17 00:00:00 2001 From: Alex Xu Date: Thu, 8 Feb 2024 13:40:35 +0800 Subject: [PATCH] api: making the value optional for JSONPatchOperation (#2522) * api: making the value optional Signed-off-by: He Jie Xu * address comments Signed-off-by: He Jie Xu * update comment Signed-off-by: He Jie Xu * generates Signed-off-by: He Jie Xu * address comments Signed-off-by: He Jie Xu * gen Signed-off-by: He Jie Xu * fix format Signed-off-by: He Jie Xu * update Signed-off-by: He Jie Xu * fix format Signed-off-by: He Jie Xu * gen again again Signed-off-by: He Jie Xu * address comments Signed-off-by: He Jie Xu * gen Signed-off-by: He Jie Xu * address comment Signed-off-by: He Jie Xu * fix test Signed-off-by: He Jie Xu --------- Signed-off-by: He Jie Xu --- api/v1alpha1/envoypatchpolicy_types.go | 6 +- api/v1alpha1/zz_generated.deepcopy.go | 7 +- ...eway.envoyproxy.io_envoypatchpolicies.yaml | 2 +- internal/ir/xds.go | 2 +- internal/ir/zz_generated.deepcopy.go | 7 +- internal/xds/translator/jsonpatch.go | 23 ++++++- .../jsonpatch-add-op-without-value.yaml | 62 ++++++++++++++++++ .../xds-ir/jsonpatch-move-op-with-value.yaml | 65 +++++++++++++++++++ ...onpatch-add-op-without-value.clusters.yaml | 14 ++++ ...npatch-add-op-without-value.endpoints.yaml | 12 ++++ ...d-op-without-value.envoypatchpolicies.yaml | 9 +++ ...npatch-add-op-without-value.listeners.yaml | 61 +++++++++++++++++ ...jsonpatch-add-op-without-value.routes.yaml | 16 +++++ ...jsonpatch-move-op-with-value.clusters.yaml | 14 ++++ ...sonpatch-move-op-with-value.endpoints.yaml | 12 ++++ ...move-op-with-value.envoypatchpolicies.yaml | 9 +++ ...sonpatch-move-op-with-value.listeners.yaml | 61 +++++++++++++++++ .../jsonpatch-move-op-with-value.routes.yaml | 16 +++++ internal/xds/translator/translator_test.go | 8 +++ site/content/en/latest/api/extension_types.md | 2 +- 20 files changed, 399 insertions(+), 9 deletions(-) create mode 100644 internal/xds/translator/testdata/in/xds-ir/jsonpatch-add-op-without-value.yaml create mode 100644 internal/xds/translator/testdata/in/xds-ir/jsonpatch-move-op-with-value.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.clusters.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.endpoints.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.envoypatchpolicies.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.listeners.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.routes.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.clusters.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.endpoints.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.envoypatchpolicies.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.listeners.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.routes.yaml diff --git a/api/v1alpha1/envoypatchpolicy_types.go b/api/v1alpha1/envoypatchpolicy_types.go index bec633692ad..d9d45ec8f44 100644 --- a/api/v1alpha1/envoypatchpolicy_types.go +++ b/api/v1alpha1/envoypatchpolicy_types.go @@ -117,8 +117,10 @@ type JSONPatchOperation struct { // Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. // +optional From *string `json:"from,omitempty"` - // Value is the new value of the path location. - Value apiextensionsv1.JSON `json:"value"` + // Value is the new value of the path location. The value is only used by + // the `add` and `replace` operations. + // +optional + Value *apiextensionsv1.JSON `json:"value,omitempty"` } // EnvoyPatchPolicyStatus defines the state of EnvoyPatchPolicy diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index aae60ea39ac..8eafea858a7 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -13,6 +13,7 @@ import ( appsv1 "k8s.io/api/apps/v1" "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" apisv1 "sigs.k8s.io/gateway-api/apis/v1" @@ -1793,7 +1794,11 @@ func (in *JSONPatchOperation) DeepCopyInto(out *JSONPatchOperation) { *out = new(string) **out = **in } - in.Value.DeepCopyInto(&out.Value) + if in.Value != nil { + in, out := &in.Value, &out.Value + *out = new(apiextensionsv1.JSON) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONPatchOperation. diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml index 67800f2c9a1..55590b7d7f0 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml @@ -79,11 +79,11 @@ spec: type: string value: description: Value is the new value of the path location. + The value is only used by the `add` and `replace` operations. x-kubernetes-preserve-unknown-fields: true required: - op - path - - value type: object type: description: Type is the typed URL of the Envoy xDS Resource diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 3ad87cf12c5..fcbd8c1fde9 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -1252,7 +1252,7 @@ type JSONPatchOperation struct { // +optional From *string `json:"from,omitempty" yaml:"from,omitempty"` // Value is the new value of the path location. - Value apiextensionsv1.JSON `json:"value" yaml:"value"` + Value *apiextensionsv1.JSON `json:"value,omitempty" yaml:"value,omitempty"` } // Tracing defines the configuration for tracing a Envoy xDS Resource diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 68e81a776ec..0381491c31d 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -11,6 +11,7 @@ package ir import ( "github.com/envoyproxy/gateway/api/v1alpha1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -996,7 +997,11 @@ func (in *JSONPatchOperation) DeepCopyInto(out *JSONPatchOperation) { *out = new(string) **out = **in } - in.Value.DeepCopyInto(&out.Value) + if in.Value != nil { + in, out := &in.Value, &out.Value + *out = new(apiextensionsv1.JSON) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONPatchOperation. diff --git a/internal/xds/translator/jsonpatch.go b/internal/xds/translator/jsonpatch.go index 2b1828f4c1e..62638e78c69 100644 --- a/internal/xds/translator/jsonpatch.go +++ b/internal/xds/translator/jsonpatch.go @@ -27,8 +27,12 @@ import ( ) const ( - AddOperation = "add" - EmptyPath = "" + AddOperation = "add" + RemoveOperation = "remove" + ReplaceOperation = "replace" + CopyOperation = "copy" + MoveOperation = "move" + EmptyPath = "" ) // processJSONPatches applies each JSONPatch to the Xds Resources for a specific type. @@ -51,6 +55,21 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []* err error ) + switch p.Operation.Op { + case AddOperation, ReplaceOperation: + if p.Operation.Value == nil { + msg := fmt.Sprintf("The %s operation requires a value", p.Operation.Op) + status.SetEnvoyPatchPolicyInvalid(e.Status, msg) + continue + } + default: + if p.Operation.Value != nil { + msg := fmt.Sprintf("The value field can not be set for the %s operation", p.Operation.Op) + status.SetEnvoyPatchPolicyInvalid(e.Status, msg) + continue + } + } + // If Path is "" and op is "add", unmarshal and add the patch as a complete // resource if p.Operation.Op == AddOperation && p.Operation.Path == EmptyPath { diff --git a/internal/xds/translator/testdata/in/xds-ir/jsonpatch-add-op-without-value.yaml b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-add-op-without-value.yaml new file mode 100644 index 00000000000..610195b2938 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-add-op-without-value.yaml @@ -0,0 +1,62 @@ +envoyPatchPolicies: +- status: {} + name: "first-policy" + namespace: "default" + jsonPatches: + - type: "type.googleapis.com/envoy.config.listener.v3.Listener" + name: "first-listener" + operation: + op: "add" + path: "/filter_chains/0/filters/0/typed_config/http_filters/0" + value: + name: "envoy.filters.http.ratelimit" + typed_config: + "@type": "type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit" + domain: "eg-ratelimit" + failure_mode_deny: true + timeout: 1s + rate_limit_service: + grpc_service: + envoy_grpc: + cluster_name: rate-limit-cluster + transport_api_version: V3 + - type: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration" + name: "first-listener" + operation: + op: "add" + path: "/virtual_hosts/0/rate_limits" +http: +- name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "*" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + tls: + alpnProtocols: + - h2 + - http/1.1 + certificates: + - name: secret-1 + # byte slice representation of "key-data" + serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] + # byte slice representation of "key-data" + privateKey: [107, 101, 121, 45, 100, 97, 116, 97] + - name: secret-2 + serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] + privateKey: [107, 101, 121, 45, 100, 97, 116, 97] + routes: + - name: "first-route" + hostname: "*" + headerMatches: + - name: user + stringMatch: + exact: "jason" + destination: + name: "first-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 diff --git a/internal/xds/translator/testdata/in/xds-ir/jsonpatch-move-op-with-value.yaml b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-move-op-with-value.yaml new file mode 100644 index 00000000000..0f7612b3408 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-move-op-with-value.yaml @@ -0,0 +1,65 @@ +envoyPatchPolicies: +- status: {} + name: "first-policy" + namespace: "default" + jsonPatches: + - type: "type.googleapis.com/envoy.config.listener.v3.Listener" + name: "first-listener" + operation: + op: "add" + path: "/filter_chains/0/filters/0/typed_config/http_filters/0" + value: + name: "envoy.filters.http.ratelimit" + typed_config: + "@type": "type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit" + domain: "eg-ratelimit" + failure_mode_deny: true + timeout: 1s + rate_limit_service: + grpc_service: + envoy_grpc: + cluster_name: rate-limit-cluster + transport_api_version: V3 + - type: "type.googleapis.com/envoy.config.listener.v3.Listener" + name: "first-listener" + operation: + op: "remove" + from: "/filter_chains/0/filters/0/typed_config/http_filters/0" + path: "/filter_chains/0/filters/0/typed_config/http_filters/1" + value: + test: "abc" +http: +- name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "*" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + tls: + alpnProtocols: + - h2 + - http/1.1 + certificates: + - name: secret-1 + # byte slice representation of "key-data" + serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] + # byte slice representation of "key-data" + privateKey: [107, 101, 121, 45, 100, 97, 116, 97] + - name: secret-2 + serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] + privateKey: [107, 101, 121, 45, 100, 97, 116, 97] + routes: + - name: "first-route" + hostname: "*" + headerMatches: + - name: user + stringMatch: + exact: "jason" + destination: + name: "first-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.clusters.yaml new file mode 100644 index 00000000000..c8692b81602 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.clusters.yaml @@ -0,0 +1,14 @@ +- commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: first-route-dest + lbPolicy: LEAST_REQUEST + name: first-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.endpoints.yaml new file mode 100644 index 00000000000..3b3f2d09076 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.endpoints.yaml @@ -0,0 +1,12 @@ +- clusterName: first-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: first-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.envoypatchpolicies.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.envoypatchpolicies.yaml new file mode 100644 index 00000000000..55cdd5c4cb2 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.envoypatchpolicies.yaml @@ -0,0 +1,9 @@ +- name: first-policy + namespace: default + status: + conditions: + - lastTransitionTime: null + message: The add operation requires a value + reason: Invalid + status: "False" + type: Programmed diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.listeners.yaml new file mode 100644 index 00000000000..f7bc0d01fc5 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.listeners.yaml @@ -0,0 +1,61 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + filterChains: + - filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.ratelimit + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit + domain: eg-ratelimit + failureModeDeny: true + rateLimitService: + grpcService: + envoyGrpc: + clusterName: rate-limit-cluster + transportApiVersion: V3 + timeout: 1s + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: first-listener + statPrefix: https + upgradeConfigs: + - upgradeType: websocket + useRemoteAddress: true + transportSocket: + name: envoy.transport_sockets.tls + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext + commonTlsContext: + alpnProtocols: + - h2 + - http/1.1 + tlsCertificateSdsSecretConfigs: + - name: secret-1 + sdsConfig: + ads: {} + resourceApiVersion: V3 + - name: secret-2 + sdsConfig: + ads: {} + resourceApiVersion: V3 + name: first-listener + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.routes.yaml new file mode 100644 index 00000000000..dc48be19646 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.routes.yaml @@ -0,0 +1,16 @@ +- ignorePortInHostMatching: true + name: first-listener + virtualHosts: + - domains: + - '*' + name: first-listener/* + routes: + - match: + headers: + - name: user + stringMatch: + exact: jason + prefix: / + name: first-route + route: + cluster: first-route-dest diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.clusters.yaml new file mode 100644 index 00000000000..c8692b81602 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.clusters.yaml @@ -0,0 +1,14 @@ +- commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: first-route-dest + lbPolicy: LEAST_REQUEST + name: first-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.endpoints.yaml new file mode 100644 index 00000000000..3b3f2d09076 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.endpoints.yaml @@ -0,0 +1,12 @@ +- clusterName: first-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: first-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.envoypatchpolicies.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.envoypatchpolicies.yaml new file mode 100644 index 00000000000..fd77280814f --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.envoypatchpolicies.yaml @@ -0,0 +1,9 @@ +- name: first-policy + namespace: default + status: + conditions: + - lastTransitionTime: null + message: The value field can not be set for the remove operation + reason: Invalid + status: "False" + type: Programmed diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.listeners.yaml new file mode 100644 index 00000000000..f7bc0d01fc5 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.listeners.yaml @@ -0,0 +1,61 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + filterChains: + - filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.ratelimit + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit + domain: eg-ratelimit + failureModeDeny: true + rateLimitService: + grpcService: + envoyGrpc: + clusterName: rate-limit-cluster + transportApiVersion: V3 + timeout: 1s + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: first-listener + statPrefix: https + upgradeConfigs: + - upgradeType: websocket + useRemoteAddress: true + transportSocket: + name: envoy.transport_sockets.tls + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext + commonTlsContext: + alpnProtocols: + - h2 + - http/1.1 + tlsCertificateSdsSecretConfigs: + - name: secret-1 + sdsConfig: + ads: {} + resourceApiVersion: V3 + - name: secret-2 + sdsConfig: + ads: {} + resourceApiVersion: V3 + name: first-listener + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.routes.yaml new file mode 100644 index 00000000000..dc48be19646 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.routes.yaml @@ -0,0 +1,16 @@ +- ignorePortInHostMatching: true + name: first-listener + virtualHosts: + - domains: + - '*' + name: first-listener/* + routes: + - match: + headers: + - name: user + stringMatch: + exact: jason + prefix: / + name: first-route + route: + cluster: first-route-dest diff --git a/internal/xds/translator/translator_test.go b/internal/xds/translator/translator_test.go index bed45e8291f..7ce9f41e195 100644 --- a/internal/xds/translator/translator_test.go +++ b/internal/xds/translator/translator_test.go @@ -177,6 +177,14 @@ func TestTranslateXds(t *testing.T) { name: "jsonpatch-invalid-patch", requireEnvoyPatchPolicies: true, }, + { + name: "jsonpatch-add-op-without-value", + requireEnvoyPatchPolicies: true, + }, + { + name: "jsonpatch-move-op-with-value", + requireEnvoyPatchPolicies: true, + }, { name: "listener-tcp-keepalive", }, diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index a61fdde76a6..7b1c9fc5033 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -1223,7 +1223,7 @@ _Appears in:_ | `op` | _[JSONPatchOperationType](#jsonpatchoperationtype)_ | true | Op is the type of operation to perform | | `path` | _string_ | true | Path is the location of the target document/field where the operation will be performed Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. | | `from` | _string_ | false | From is the source location of the value to be copied or moved. Only valid for move or copy operations Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. | -| `value` | _[JSON](#json)_ | true | Value is the new value of the path location. | +| `value` | _[JSON](#json)_ | false | Value is the new value of the path location. The value is only used by the `add` and `replace` operations. | #### JSONPatchOperationType