Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions api/v1alpha1/envoypatchpolicy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,21 @@ const (
)

// EnvoyJSONPatchConfig defines the configuration for patching a Envoy xDS Resource
// using JSONPatch semantic
// using JSONPatch semantics.
//
// +kubebuilder:validation:XValidation:rule="!(has(self.name) && has(self.nameSelector))",message="only one of name and nameSelector can be specified"
// +kubebuilder:validation:XValidation:rule="has(self.name) || has(self.nameSelector)",message="either name or nameSelector must be specified"
type EnvoyJSONPatchConfig struct {
// Type is the typed URL of the Envoy xDS Resource
Type EnvoyResourceType `json:"type"`
// Name is the name of the resource
Name string `json:"name"`
// Name is the name of the resource.
//
// +optional
Name *string `json:"name,omitempty"`
// NameSelector is a StringMatch that is used to select the resources to patch based on their name.
//
// +optional
NameSelector *StringMatch `json:"nameSelector,omitempty"`
Comment thread
zirain marked this conversation as resolved.
// Patch defines the JSON Patch Operation
Operation JSONPatchOperation `json:"operation"`
}
Expand Down
10 changes: 10 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,33 @@ spec:
items:
description: |-
EnvoyJSONPatchConfig defines the configuration for patching a Envoy xDS Resource
using JSONPatch semantic
using JSONPatch semantics.
properties:
name:
description: Name is the name of the resource
description: Name is the name of the resource.
type: string
nameSelector:
description: NameSelector is a StringMatch that is used to select
the resources to patch based on their name.
properties:
type:
default: Exact
description: Type specifies how to match against a string.
enum:
- Exact
- Prefix
- Suffix
- RegularExpression
type: string
value:
description: Value specifies the string value that the match
must have.
maxLength: 1024
minLength: 1
type: string
required:
- value
type: object
operation:
description: Patch defines the JSON Patch Operation
properties:
Expand Down Expand Up @@ -117,10 +139,14 @@ spec:
- type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret
type: string
required:
- name
- operation
- type
type: object
x-kubernetes-validations:
- message: only one of name and nameSelector can be specified
rule: '!(has(self.name) && has(self.nameSelector))'
- message: either name or nameSelector must be specified
rule: has(self.name) || has(self.nameSelector)
type: array
priority:
description: |-
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,33 @@ spec:
items:
description: |-
EnvoyJSONPatchConfig defines the configuration for patching a Envoy xDS Resource
using JSONPatch semantic
using JSONPatch semantics.
properties:
name:
description: Name is the name of the resource
description: Name is the name of the resource.
type: string
nameSelector:
description: NameSelector is a StringMatch that is used to select
the resources to patch based on their name.
properties:
type:
default: Exact
description: Type specifies how to match against a string.
enum:
- Exact
- Prefix
- Suffix
- RegularExpression
type: string
value:
description: Value specifies the string value that the match
must have.
maxLength: 1024
minLength: 1
type: string
required:
- value
type: object
operation:
description: Patch defines the JSON Patch Operation
properties:
Expand Down Expand Up @@ -116,10 +138,14 @@ spec:
- type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret
type: string
required:
- name
- operation
- type
type: object
x-kubernetes-validations:
- message: only one of name and nameSelector can be specified
rule: '!(has(self.name) && has(self.nameSelector))'
- message: either name or nameSelector must be specified
rule: has(self.name) || has(self.nameSelector)
type: array
priority:
description: |-
Expand Down
67 changes: 64 additions & 3 deletions internal/gatewayapi/envoypatchpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ package gatewayapi

import (
"fmt"
"regexp"

"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/ptr"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"

egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
Expand Down Expand Up @@ -126,10 +128,36 @@ func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.Envo
}

// Save the patch
policyRejected := false
for _, patch := range policy.Spec.JSONPatches {
irPatch := ir.JSONPatchConfig{}
irPatch.Type = string(patch.Type)
irPatch.Name = patch.Name
irPatch.Name = ir.StringMatch{
Exact: patch.Name,
}
if patch.NameSelector != nil {
irPatch.Name = *toIRStringMatch(patch.NameSelector)
}
// Validate that regex is valid if it's a regex match
if r := irPatch.Name.SafeRegex; r != nil {
_, err := regexp.Compile(*r)
if err != nil {
message := fmt.Sprintf("invalid regex in NameSelector: %v", err)
resolveErr = &status.PolicyResolveError{
Reason: egv1a1.PolicyReasonInvalid,
Message: message,
}
status.SetResolveErrorForPolicyAncestor(&policy.Status,
&ancestorRef,
t.GatewayControllerName,
policy.Generation,
resolveErr,
)

policyRejected = true
break
}
}
irPatch.Operation.Op = ir.JSONPatchOp(patch.Operation.Op)
irPatch.Operation.Path = patch.Operation.Path
irPatch.Operation.JSONPath = patch.Operation.JSONPath
Expand All @@ -139,9 +167,42 @@ func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.Envo
policyIR.JSONPatches = append(policyIR.JSONPatches, &irPatch)
}

// Set Accepted=True
status.SetAcceptedForPolicyAncestor(&policy.Status, &ancestorRef, t.GatewayControllerName, policy.Generation)
// Only set Accepted=True if policy was not rejected due to validation errors
if !policyRejected {
// Set Accepted=True
status.SetAcceptedForPolicyAncestor(&policy.Status, &ancestorRef, t.GatewayControllerName, policy.Generation)
} else {
// Clear any partial patches that were added before validation failed
policyIR.JSONPatches = nil

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.

this is changing the existing logic, curious why we are doing it in this PR

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

}
}

return res
}

func toIRStringMatch(sm *egv1a1.StringMatch) *ir.StringMatch {
if sm == nil {
return nil
}

switch ptr.Deref(sm.Type, egv1a1.StringMatchExact) {
case egv1a1.StringMatchExact:
return &ir.StringMatch{
Exact: &sm.Value,
}
case egv1a1.StringMatchPrefix:
return &ir.StringMatch{
Prefix: &sm.Value,
}
case egv1a1.StringMatchSuffix:
return &ir.StringMatch{
Suffix: &sm.Value,
}
case egv1a1.StringMatchRegularExpression:
return &ir.StringMatch{
SafeRegex: &sm.Value,
}
default:
return nil
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,10 @@ xdsIR:
- path: /dev/stdout
envoyPatchPolicies:
- jsonPatches:
- name: envoy-gateway-gateway-1-http
- name:
distinct: false
exact: envoy-gateway-gateway-1-http
name: ""
operation:
op: replace
path: /ignore_global_conn_limit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ envoyPatchPolicies:
metadata:
namespace: envoy-gateway
name: gateway-not-exists
generation: 10
spec:
type: "JSONPatch"
targetRef:
Expand All @@ -23,7 +22,6 @@ envoyPatchPolicies:
metadata:
namespace: envoy-gateway
name: edit-ignore-global-limit
generation: 10
spec:
type: "JSONPatch"
targetRef:
Expand All @@ -39,6 +37,26 @@ envoyPatchPolicies:
op: replace
path: "/ignore_global_conn_limit"
value: "true"
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyPatchPolicy
metadata:
namespace: envoy-gateway
name: invalid-regex
spec:
type: "JSONPatch"
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-not-exists
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
nameSelector:
type: RegularExpression
value: "*.illegal.regex"
operation:
op: replace
path: "/per_connection_buffer_limit_bytes"
value: "1024"
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ envoyPatchPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyPatchPolicy
metadata:
generation: 10
name: gateway-not-exists
namespace: envoy-gateway
spec:
Expand All @@ -23,7 +22,6 @@ envoyPatchPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyPatchPolicy
metadata:
generation: 10
name: edit-ignore-global-limit
namespace: envoy-gateway
spec:
Expand All @@ -50,11 +48,32 @@ envoyPatchPolicies:
conditions:
- lastTransitionTime: null
message: Policy has been accepted.
observedGeneration: 10
reason: Accepted
status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyPatchPolicy
metadata:
name: invalid-regex
namespace: envoy-gateway
spec:
jsonPatches:
- nameSelector:
type: RegularExpression
value: '*.illegal.regex'
operation:
op: replace
path: /per_connection_buffer_limit_bytes
value: "1024"
type: type.googleapis.com/envoy.config.listener.v3.Listener
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-not-exists
type: JSONPatch
status:
ancestors: null
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
Expand Down Expand Up @@ -120,9 +139,11 @@ xdsIR:
json:
- path: /dev/stdout
envoyPatchPolicies:
- generation: 10
jsonPatches:
- name: envoy-gateway-gateway-1-http
- jsonPatches:
- name:
distinct: false
exact: envoy-gateway-gateway-1-http
name: ""
operation:
op: replace
path: /ignore_global_conn_limit
Expand All @@ -140,7 +161,6 @@ xdsIR:
conditions:
- lastTransitionTime: null
message: Policy has been accepted.
observedGeneration: 10
reason: Accepted
status: "True"
type: Accepted
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,10 @@ xdsIR:
- path: /dev/stdout
envoyPatchPolicies:
- jsonPatches:
- name: envoy-gateway-gateway-1-http
- name:
distinct: false
exact: envoy-gateway-gateway-1-http
name: ""
operation:
op: replace
path: /per_connection_buffer_limit_bytes
Expand All @@ -159,7 +162,10 @@ xdsIR:
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- jsonPatches:
- name: envoy-gateway-gateway-1-http
- name:
distinct: false
exact: envoy-gateway-gateway-1-http
name: ""
operation:
op: replace
path: /ignore_global_conn_limit
Expand Down
Loading
Loading