Skip to content

Commit

Permalink
feat(translator): implement connection limit (envoyproxy#2952)
Browse files Browse the repository at this point in the history
* implement connection limit

Signed-off-by: Guy Daich <[email protected]>

* fix lint

Signed-off-by: Guy Daich <[email protected]>

* fix lint 2

Signed-off-by: Guy Daich <[email protected]>

* fix ir, coverage

Signed-off-by: Guy Daich <[email protected]>

* fix lint 3

Signed-off-by: Guy Daich <[email protected]>

* open more connection in e2e

Signed-off-by: Guy Daich <[email protected]>

* fix error type

Signed-off-by: Guy Daich <[email protected]>

* add additional connections

Signed-off-by: Guy Daich <[email protected]>

* make limit value required

Signed-off-by: Guy Daich <[email protected]>

* add error-flow unit test

Signed-off-by: Guy Daich <[email protected]>

* fix lint 4

Signed-off-by: Guy Daich <[email protected]>

* assert policy accepted in test

Signed-off-by: Guy Daich <[email protected]>

* rename limit => connectionLimit

Signed-off-by: Guy Daich <[email protected]>

---------

Signed-off-by: Guy Daich <[email protected]>
Co-authored-by: zirain <[email protected]>
  • Loading branch information
guydc and zirain authored Mar 26, 2024
1 parent 275b5db commit decd878
Show file tree
Hide file tree
Showing 26 changed files with 1,310 additions and 36 deletions.
7 changes: 3 additions & 4 deletions api/v1alpha1/connection_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,19 @@ import gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"

// Connection allows users to configure connection-level settings
type Connection struct {
// Limit defines limits related to connections
// ConnectionLimit defines limits related to connections
//
// +optional
Limit *ConnectionLimit `json:"limit,omitempty"`
ConnectionLimit *ConnectionLimit `json:"connectionLimit,omitempty"`
}

type ConnectionLimit struct {
// Value of the maximum concurrent connections limit.
// When the limit is reached, incoming connections will be closed after the CloseDelay duration.
// Default: unlimited.
//
// +optional
// +kubebuilder:validation:Minimum=0
Value *int64 `json:"value,omitempty"`
Value int64 `json:"value,omitempty"`

// CloseDelay defines the delay to use before closing connections that are rejected
// once the limit value is reached.
Expand Down
9 changes: 2 additions & 7 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 @@ -94,8 +94,8 @@ spec:
connection:
description: Connection includes client connection settings.
properties:
limit:
description: Limit defines limits related to connections
connectionLimit:
description: ConnectionLimit defines limits related to connections
properties:
closeDelay:
description: 'CloseDelay defines the delay to use before closing
Expand Down
34 changes: 34 additions & 0 deletions internal/gatewayapi/clienttrafficpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,11 @@ func (t *Translator) translateClientTrafficPolicyForListener(policy *egv1a1.Clie
// Translate TCPKeepalive
translateListenerTCPKeepalive(policy.Spec.TCPKeepalive, httpIR)

// Translate Connection
if err := translateListenerConnection(policy.Spec.Connection, httpIR); err != nil {
return err
}

// Translate Proxy Protocol
translateListenerProxyProtocol(policy.Spec.EnableProxyProtocol, httpIR)

Expand Down Expand Up @@ -644,3 +649,32 @@ func (t *Translator) translateListenerTLSParameters(policy *egv1a1.ClientTraffic

return nil
}

func translateListenerConnection(connection *egv1a1.Connection, httpIR *ir.HTTPListener) error {
// Return early if not set
if connection == nil {
return nil
}

irConnection := &ir.Connection{}

if connection.ConnectionLimit != nil {
irConnectionLimit := &ir.ConnectionLimit{}

irConnectionLimit.Value = ptr.To(uint64(connection.ConnectionLimit.Value))

if connection.ConnectionLimit.CloseDelay != nil {
d, err := time.ParseDuration(string(*connection.ConnectionLimit.CloseDelay))
if err != nil {
return fmt.Errorf("invalid CloseDelay value %s", *connection.ConnectionLimit.CloseDelay)
}
irConnectionLimit.CloseDelay = ptr.To(metav1.Duration{Duration: d})
}

irConnection.Limit = irConnectionLimit
}

httpIR.Connection = irConnection

return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
clientTrafficPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
namespace: envoy-gateway
name: target-gateway-1
spec:
tcpKeepalive: {}
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
namespace: envoy-gateway
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
namespace: envoy-gateway
name: target-gateway-1-section-http-1
spec:
connection:
connectionLimit:
value: 3
closeDelay: 10mib
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
sectionName: http-1
namespace: envoy-gateway
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-1
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http-1
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
- name: http-2
protocol: HTTP
port: 8080
allowedRoutes:
namespaces:
from: Same
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
clientTrafficPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
creationTimestamp: null
name: target-gateway-1-section-http-1
namespace: envoy-gateway
spec:
connection:
connectionLimit:
closeDelay: 10mib
value: 3
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
namespace: envoy-gateway
sectionName: http-1
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
namespace: envoy-gateway
sectionName: http-1
conditions:
- lastTransitionTime: null
message: Invalid CloseDelay value 10mib
reason: Invalid
status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
creationTimestamp: null
name: target-gateway-1
namespace: envoy-gateway
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
namespace: envoy-gateway
tcpKeepalive: {}
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
message: There are existing ClientTrafficPolicies that are overriding these
sections [http-1]
reason: Overridden
status: "True"
type: Overridden
- lastTransitionTime: null
message: Policy has been accepted.
reason: Accepted
status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
creationTimestamp: null
name: gateway-1
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
listeners:
- allowedRoutes:
namespaces:
from: Same
name: http-1
port: 80
protocol: HTTP
- allowedRoutes:
namespaces:
from: Same
name: http-2
port: 8080
protocol: HTTP
status:
listeners:
- attachedRoutes: 0
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: null
message: Listener has been successfully translated
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: null
message: Listener references have been resolved
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
name: http-1
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
- attachedRoutes: 0
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: null
message: Listener has been successfully translated
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: null
message: Listener references have been resolved
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
name: http-2
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
infraIR:
envoy-gateway/gateway-1:
proxy:
listeners:
- address: null
name: envoy-gateway/gateway-1/http-1
ports:
- containerPort: 10080
name: http-1
protocol: HTTP
servicePort: 80
- address: null
name: envoy-gateway/gateway-1/http-2
ports:
- containerPort: 8080
name: http-2
protocol: HTTP
servicePort: 8080
metadata:
labels:
gateway.envoyproxy.io/owning-gateway-name: gateway-1
gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
name: envoy-gateway/gateway-1
xdsIR:
envoy-gateway/gateway-1:
accessLog:
text:
- path: /dev/stdout
http:
- address: 0.0.0.0
hostnames:
- '*'
isHTTP2: false
name: envoy-gateway/gateway-1/http-1
path:
escapedSlashesAction: UnescapeAndRedirect
mergeSlashes: true
port: 10080
- address: 0.0.0.0
hostnames:
- '*'
isHTTP2: false
name: envoy-gateway/gateway-1/http-2
path:
escapedSlashesAction: UnescapeAndRedirect
mergeSlashes: true
port: 8080
tcpKeepalive: {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
clientTrafficPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
namespace: envoy-gateway
name: target-gateway-1
spec:
connection: {}
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
namespace: envoy-gateway
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
namespace: envoy-gateway
name: target-gateway-1-section-http-1
spec:
connection:
connectionLimit:
value: 3
closeDelay: 10s
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
sectionName: http-1
namespace: envoy-gateway
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-1
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http-1
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
- name: http-2
protocol: HTTP
port: 8080
allowedRoutes:
namespaces:
from: Same
Loading

0 comments on commit decd878

Please sign in to comment.