Skip to content

Commit

Permalink
crd/ContourDeployment: Add field for set externalTrafficPolicy for se…
Browse files Browse the repository at this point in the history
…rvice/envoy (#4803)


Signed-off-by: Gang Liu <gang.liu@daocloud.io>
  • Loading branch information
izturn authored Nov 2, 2022
1 parent 55f5ee5 commit 4badccc
Show file tree
Hide file tree
Showing 15 changed files with 135 additions and 7 deletions.
9 changes: 9 additions & 0 deletions apis/projectcontour/v1alpha1/contourdeployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,15 @@ type NetworkPublishing struct {
// +optional
Type NetworkPublishingType `json:"type,omitempty"`

// ExternalTrafficPolicy describes how nodes distribute service traffic they
// receive on one of the Service's "externally-facing" addresses (NodePorts, ExternalIPs,
// and LoadBalancer IPs).
//
// If unset, defaults to "Local".
//
// +optional
ExternalTrafficPolicy corev1.ServiceExternalTrafficPolicyType `json:"externalTrafficPolicy,omitempty"`

// ServiceAnnotations is the annotations to add to
// the provisioned Envoy service.
//
Expand Down
1 change: 1 addition & 0 deletions changelogs/unreleased/4803-izturn-small.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add Service/Envoy's ExternalTrafficPolicy configurability to ContourDeployment resource.
6 changes: 6 additions & 0 deletions examples/contour/01-crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2571,6 +2571,12 @@ spec:
description: NetworkPublishing defines how to expose Envoy to
a network.
properties:
externalTrafficPolicy:
description: "ExternalTrafficPolicy describes how nodes distribute
service traffic they receive on one of the Service's \"externally-facing\"
addresses (NodePorts, ExternalIPs, and LoadBalancer IPs).
\n If unset, defaults to \"Local\"."
type: string
serviceAnnotations:
additionalProperties:
type: string
Expand Down
6 changes: 6 additions & 0 deletions examples/render/contour-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2780,6 +2780,12 @@ spec:
description: NetworkPublishing defines how to expose Envoy to
a network.
properties:
externalTrafficPolicy:
description: "ExternalTrafficPolicy describes how nodes distribute
service traffic they receive on one of the Service's \"externally-facing\"
addresses (NodePorts, ExternalIPs, and LoadBalancer IPs).
\n If unset, defaults to \"Local\"."
type: string
serviceAnnotations:
additionalProperties:
type: string
Expand Down
6 changes: 6 additions & 0 deletions examples/render/contour-gateway-provisioner.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2585,6 +2585,12 @@ spec:
description: NetworkPublishing defines how to expose Envoy to
a network.
properties:
externalTrafficPolicy:
description: "ExternalTrafficPolicy describes how nodes distribute
service traffic they receive on one of the Service's \"externally-facing\"
addresses (NodePorts, ExternalIPs, and LoadBalancer IPs).
\n If unset, defaults to \"Local\"."
type: string
serviceAnnotations:
additionalProperties:
type: string
Expand Down
6 changes: 6 additions & 0 deletions examples/render/contour-gateway.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2786,6 +2786,12 @@ spec:
description: NetworkPublishing defines how to expose Envoy to
a network.
properties:
externalTrafficPolicy:
description: "ExternalTrafficPolicy describes how nodes distribute
service traffic they receive on one of the Service's \"externally-facing\"
addresses (NodePorts, ExternalIPs, and LoadBalancer IPs).
\n If unset, defaults to \"Local\"."
type: string
serviceAnnotations:
additionalProperties:
type: string
Expand Down
6 changes: 6 additions & 0 deletions examples/render/contour.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2780,6 +2780,12 @@ spec:
description: NetworkPublishing defines how to expose Envoy to
a network.
properties:
externalTrafficPolicy:
description: "ExternalTrafficPolicy describes how nodes distribute
service traffic they receive on one of the Service's \"externally-facing\"
addresses (NodePorts, ExternalIPs, and LoadBalancer IPs).
\n If unset, defaults to \"Local\"."
type: string
serviceAnnotations:
additionalProperties:
type: string
Expand Down
5 changes: 5 additions & 0 deletions internal/provisioner/controller/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@ func (r *gatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
if networkPublishing.Type != "" {
contourModel.Spec.NetworkPublishing.Envoy.Type = networkPublishing.Type
}

if networkPublishing.ExternalTrafficPolicy != "" {
contourModel.Spec.NetworkPublishing.Envoy.ExternalTrafficPolicy = networkPublishing.ExternalTrafficPolicy
}

contourModel.Spec.NetworkPublishing.Envoy.ServiceAnnotations = networkPublishing.ServiceAnnotations
}

Expand Down
7 changes: 4 additions & 3 deletions internal/provisioner/controller/gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1015,7 +1015,8 @@ func TestGatewayReconcile(t *testing.T) {
Spec: contourv1alpha1.ContourDeploymentSpec{
Envoy: &contourv1alpha1.EnvoySettings{
NetworkPublishing: &contourv1alpha1.NetworkPublishing{
Type: contourv1alpha1.ClusterIPServicePublishingType,
Type: contourv1alpha1.NodePortServicePublishingType,
ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyTypeCluster,
ServiceAnnotations: map[string]string{
"key-1": "val-1",
"key-2": "val-2",
Expand Down Expand Up @@ -1050,8 +1051,8 @@ func TestGatewayReconcile(t *testing.T) {
},
}
require.NoError(t, r.client.Get(context.Background(), keyFor(svc), svc))

assert.Equal(t, corev1.ServiceTypeClusterIP, svc.Spec.Type)
assert.Equal(t, corev1.ServiceExternalTrafficPolicyTypeCluster, svc.Spec.ExternalTrafficPolicy)
assert.Equal(t, corev1.ServiceTypeNodePort, svc.Spec.Type)
require.Len(t, svc.Annotations, 2)
assert.Equal(t, "val-1", svc.Annotations["key-1"])
assert.Equal(t, "val-2", svc.Annotations["key-2"])
Expand Down
12 changes: 11 additions & 1 deletion internal/provisioner/controller/gatewayclass.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ import (
"fmt"
"strings"

"github.com/go-logr/logr"
"github.com/projectcontour/contour/apis/projectcontour/v1alpha1"
contour_api_v1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1"

"github.com/go-logr/logr"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
Expand Down Expand Up @@ -181,6 +183,14 @@ func (r *gatewayClassReconciler) Reconcile(ctx context.Context, req ctrl.Request
params.Spec.Envoy.NetworkPublishing.Type)
invalidParamsMessages = append(invalidParamsMessages, msg)
}

switch params.Spec.Envoy.NetworkPublishing.ExternalTrafficPolicy {
case "", corev1.ServiceExternalTrafficPolicyTypeCluster, corev1.ServiceExternalTrafficPolicyTypeLocal:
default:
msg := fmt.Sprintf("invalid ContourDeployment spec.envoy.networkPublishing.externalTrafficPolicy %q, must be Local or Cluster",
params.Spec.Envoy.NetworkPublishing.ExternalTrafficPolicy)
invalidParamsMessages = append(invalidParamsMessages, msg)
}
}

if params.Spec.Envoy.ExtraVolumeMounts != nil {
Expand Down
34 changes: 34 additions & 0 deletions internal/provisioner/controller/gatewayclass_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,40 @@ func TestGatewayClassReconcile(t *testing.T) {
Reason: string(gatewayv1beta1.GatewayClassReasonInvalidParameters),
},
},
"gatewayclass controlled by us with a valid parametersRef but invalid parameter values for ExternalTrafficPolicy gets Accepted: false condition": {
gatewayClass: &gatewayv1beta1.GatewayClass{
ObjectMeta: metav1.ObjectMeta{
Name: "gatewayclass-1",
},
Spec: gatewayv1beta1.GatewayClassSpec{
ControllerName: "projectcontour.io/gateway-controller",
ParametersRef: &gatewayv1beta1.ParametersReference{
Group: "projectcontour.io",
Kind: "ContourDeployment",
Name: "gatewayclass-params",
Namespace: gatewayapi.NamespacePtr("projectcontour"),
},
},
},
params: &contourv1alpha1.ContourDeployment{
ObjectMeta: metav1.ObjectMeta{
Namespace: "projectcontour",
Name: "gatewayclass-params",
},
Spec: contourv1alpha1.ContourDeploymentSpec{
Envoy: &contourv1alpha1.EnvoySettings{
NetworkPublishing: &contourv1alpha1.NetworkPublishing{
ExternalTrafficPolicy: "invalid-external-traffic-policy",
},
},
},
},
wantCondition: &metav1.Condition{
Type: string(gatewayv1beta1.GatewayClassConditionStatusAccepted),
Status: metav1.ConditionFalse,
Reason: string(gatewayv1beta1.GatewayClassReasonInvalidParameters),
},
},
}

for name, tc := range tests {
Expand Down
10 changes: 9 additions & 1 deletion internal/provisioner/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ func Default(namespace, name string) *Contour {
EnvoyLogLevel: contourv1alpha1.InfoLog,
NetworkPublishing: NetworkPublishing{
Envoy: EnvoyNetworkPublishing{
Type: LoadBalancerServicePublishingType,
Type: LoadBalancerServicePublishingType,
ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyTypeLocal,
ContainerPorts: []ContainerPort{
{
Name: "http",
Expand Down Expand Up @@ -366,6 +367,13 @@ type EnvoyNetworkPublishing struct {

// ServiceAnnotations is a set of annotations to add to the provisioned Envoy service.
ServiceAnnotations map[string]string

// ExternalTrafficPolicy describes how nodes distribute service traffic they
// receive on one of the Service's "externally-facing" addresses (NodePorts, ExternalIPs,
// and LoadBalancer IPs).
//
// If unset, defaults to "Local".
ExternalTrafficPolicy corev1.ServiceExternalTrafficPolicyType
}

type NetworkPublishingType = contourv1alpha1.NetworkPublishingType
Expand Down
2 changes: 1 addition & 1 deletion internal/provisioner/objects/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ func DesiredEnvoyService(contour *model.Contour) *corev1.Service {
epType := contour.Spec.NetworkPublishing.Envoy.Type
if epType == model.LoadBalancerServicePublishingType ||
epType == model.NodePortServicePublishingType {
svc.Spec.ExternalTrafficPolicy = corev1.ServiceExternalTrafficPolicyTypeLocal
svc.Spec.ExternalTrafficPolicy = contour.Spec.NetworkPublishing.Envoy.ExternalTrafficPolicy
}
switch epType {
case model.LoadBalancerServicePublishingType:
Expand Down
14 changes: 13 additions & 1 deletion internal/provisioner/objects/service/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@ func checkServiceHasExternalTrafficPolicy(t *testing.T, svc *corev1.Service, pol
}
}

func checkServiceHasNoExternalTrafficPolicy(t *testing.T, svc *corev1.Service) {
t.Helper()

if svc.Spec.ExternalTrafficPolicy != "" {
t.Errorf("service has invalid external traffic policy type %s", svc.Spec.ExternalTrafficPolicy)
}
}
func checkServiceHasLoadBalancerAddress(t *testing.T, svc *corev1.Service, address string) {
t.Helper()

Expand Down Expand Up @@ -177,14 +184,19 @@ func TestDesiredEnvoyService(t *testing.T) {
checkServiceHasPortName(t, svc, "https")
checkServiceHasPortProtocol(t, svc, corev1.ProtocolTCP)

cntr.Spec.NetworkPublishing.Envoy.Type = model.ClusterIPServicePublishingType
svc = DesiredEnvoyService(cntr)
checkServiceHasNoExternalTrafficPolicy(t, svc)

// Check LB annotations for the different provider types, starting with AWS ELB (the default
// if AWS provider params are not passed).
cntr.Spec.NetworkPublishing.Envoy.Type = model.LoadBalancerServicePublishingType
cntr.Spec.NetworkPublishing.Envoy.ExternalTrafficPolicy = corev1.ServiceExternalTrafficPolicyTypeCluster
cntr.Spec.NetworkPublishing.Envoy.LoadBalancer.Scope = model.ExternalLoadBalancer
cntr.Spec.NetworkPublishing.Envoy.LoadBalancer.ProviderParameters.Type = model.AWSLoadBalancerProvider
svc = DesiredEnvoyService(cntr)
checkServiceHasType(t, svc, corev1.ServiceTypeLoadBalancer)
checkServiceHasExternalTrafficPolicy(t, svc, corev1.ServiceExternalTrafficPolicyTypeLocal)
checkServiceHasExternalTrafficPolicy(t, svc, corev1.ServiceExternalTrafficPolicyTypeCluster)
checkServiceHasAnnotations(t, svc, awsLbBackendProtoAnnotation, awsLBProxyProtocolAnnotation)

// Test proxy protocol for AWS Classic load balancer (when provider params are specified).
Expand Down
18 changes: 18 additions & 0 deletions site/content/docs/main/config/api-reference.html
Original file line number Diff line number Diff line change
Expand Up @@ -6998,6 +6998,24 @@ <h3 id="projectcontour.io/v1alpha1.NetworkPublishing">NetworkPublishing
</tr>
<tr>
<td style="white-space:nowrap">
<code>externalTrafficPolicy</code>
<br>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#serviceexternaltrafficpolicytype-v1-core">
Kubernetes core/v1.ServiceExternalTrafficPolicyType
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>ExternalTrafficPolicy describes how nodes distribute service traffic they
receive on one of the Service&rsquo;s &ldquo;externally-facing&rdquo; addresses (NodePorts, ExternalIPs,
and LoadBalancer IPs).</p>
<p>If unset, defaults to &ldquo;Local&rdquo;.</p>
</td>
</tr>
<tr>
<td style="white-space:nowrap">
<code>serviceAnnotations</code>
<br>
<em>
Expand Down

0 comments on commit 4badccc

Please sign in to comment.