Skip to content

Commit

Permalink
add disabled-features flag to ContourDeployment for provisioner (#6152)
Browse files Browse the repository at this point in the history
Fixes #5276.

Signed-off-by: Lubron Zhan <[email protected]>
  • Loading branch information
lubronzhan authored Feb 9, 2024
1 parent 0160b09 commit 39a7d20
Show file tree
Hide file tree
Showing 24 changed files with 733 additions and 53 deletions.
3 changes: 3 additions & 0 deletions apis/projectcontour/v1/httpproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -1514,3 +1514,6 @@ type SlowStartPolicy struct {
// +kubebuilder:validation:Maximum=100
MinimumWeightPercent uint32 `json:"minWeightPercent"`
}

// +kubebuilder:validation:Enum=grpcroutes;tlsroutes;extensionservices;backendtlspolicies
type Feature string
22 changes: 0 additions & 22 deletions apis/projectcontour/v1/httpproxy_helpers.go

This file was deleted.

8 changes: 8 additions & 0 deletions apis/projectcontour/v1alpha1/contourdeployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,14 @@ type ContourSettings struct {
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=42
WatchNamespaces []contour_api_v1.Namespace `json:"watchNamespaces,omitempty"`

// DisabledFeatures defines an array of resources that will be ignored by
// contour reconciler.
// +optional
// +kubebuilder:validation:Type=array
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=42
DisabledFeatures []contour_api_v1.Feature `json:"disabledFeatures,omitempty"`
}

// DeploymentSettings contains settings for Deployment resources.
Expand Down
7 changes: 7 additions & 0 deletions changelogs/unreleased/6152-lubronzhan-minor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## Add DisabledFeatures to ContourDeployment for gateway provisioner

A new flag DisabledFeatures is added to ContourDeployment so that user can configure contour which is deployed by the provisioner to skip reconciling CRDs which are specified inside the flag.

Accepted values are `grpcroutes|tlsroutes|extensionservices|backendtlspolicies`.


14 changes: 14 additions & 0 deletions examples/contour/01-crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,20 @@ spec:
type: string
type: object
type: object
disabledFeatures:
description: |-
DisabledFeatures defines an array of resources that will be ignored by
contour reconciler.
items:
enum:
- grpcroutes
- tlsroutes
- extensionservices
- backendtlspolicies
type: string
maxItems: 42
minItems: 1
type: array
kubernetesLogLevel:
description: |-
KubernetesLogLevel Enable Kubernetes client debug logging with log level. If unset,
Expand Down
14 changes: 14 additions & 0 deletions examples/render/contour-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1698,6 +1698,20 @@ spec:
type: string
type: object
type: object
disabledFeatures:
description: |-
DisabledFeatures defines an array of resources that will be ignored by
contour reconciler.
items:
enum:
- grpcroutes
- tlsroutes
- extensionservices
- backendtlspolicies
type: string
maxItems: 42
minItems: 1
type: array
kubernetesLogLevel:
description: |-
KubernetesLogLevel Enable Kubernetes client debug logging with log level. If unset,
Expand Down
14 changes: 14 additions & 0 deletions examples/render/contour-gateway-provisioner.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1490,6 +1490,20 @@ spec:
type: string
type: object
type: object
disabledFeatures:
description: |-
DisabledFeatures defines an array of resources that will be ignored by
contour reconciler.
items:
enum:
- grpcroutes
- tlsroutes
- extensionservices
- backendtlspolicies
type: string
maxItems: 42
minItems: 1
type: array
kubernetesLogLevel:
description: |-
KubernetesLogLevel Enable Kubernetes client debug logging with log level. If unset,
Expand Down
14 changes: 14 additions & 0 deletions examples/render/contour-gateway.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1701,6 +1701,20 @@ spec:
type: string
type: object
type: object
disabledFeatures:
description: |-
DisabledFeatures defines an array of resources that will be ignored by
contour reconciler.
items:
enum:
- grpcroutes
- tlsroutes
- extensionservices
- backendtlspolicies
type: string
maxItems: 42
minItems: 1
type: array
kubernetesLogLevel:
description: |-
KubernetesLogLevel Enable Kubernetes client debug logging with log level. If unset,
Expand Down
14 changes: 14 additions & 0 deletions examples/render/contour.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1698,6 +1698,20 @@ spec:
type: string
type: object
type: object
disabledFeatures:
description: |-
DisabledFeatures defines an array of resources that will be ignored by
contour reconciler.
items:
enum:
- grpcroutes
- tlsroutes
- extensionservices
- backendtlspolicies
type: string
maxItems: 42
minItems: 1
type: array
kubernetesLogLevel:
description: |-
KubernetesLogLevel Enable Kubernetes client debug logging with log level. If unset,
Expand Down
5 changes: 3 additions & 2 deletions internal/provisioner/controller/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"context"
"fmt"

contour_api_v1 "github.com/projectcontour/contour/apis/projectcontour/v1"
contour_api_v1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1"
"github.com/projectcontour/contour/internal/gatewayapi"
"github.com/projectcontour/contour/internal/provisioner/model"
Expand Down Expand Up @@ -262,7 +261,9 @@ func (r *gatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct

contourModel.Spec.KubernetesLogLevel = contourParams.KubernetesLogLevel

contourModel.Spec.WatchNamespaces = contour_api_v1.NamespacesToStrings(contourParams.WatchNamespaces)
contourModel.Spec.WatchNamespaces = contourParams.WatchNamespaces

contourModel.Spec.DisabledFeatures = contourParams.DisabledFeatures

if contourParams.Deployment != nil &&
contourParams.Deployment.Strategy != nil {
Expand Down
23 changes: 22 additions & 1 deletion internal/provisioner/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package model

import (
contourv1 "github.com/projectcontour/contour/apis/projectcontour/v1"
contourv1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1"
"github.com/projectcontour/contour/internal/ref"

Expand Down Expand Up @@ -253,7 +254,27 @@ type ContourSpec struct {
// WatchNamespaces is an array of namespaces. Setting it will instruct the contour instance
// to only watch these set of namespaces
// default is nil, contour will watch resource of all namespaces
WatchNamespaces []string
WatchNamespaces []contourv1.Namespace

// DisabledFeatures defines an array of resources that will be ignored by
// contour reconciler.
DisabledFeatures []contourv1.Feature
}

func NamespacesToStrings(ns []contourv1.Namespace) []string {
res := make([]string, len(ns))
for i, n := range ns {
res[i] = string(n)
}
return res
}

func FeaturesToStrings(fs []contourv1.Feature) []string {
res := make([]string, len(fs))
for i := range fs {
res[i] = string(fs[i])
}
return res
}

// WorkloadType is the type of Kubernetes workload to use for a component.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,29 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package v1
package model

import (
"reflect"
"testing"

contourv1 "github.com/projectcontour/contour/apis/projectcontour/v1"
)

func TestNamespacesToStrings(t *testing.T) {
testCases := []struct {
description string
namespaces []Namespace
namespaces []contourv1.Namespace
expectStrings []string
}{
{
description: "namespace 1",
namespaces: []Namespace{},
description: "no namespaces",
namespaces: []contourv1.Namespace{},
expectStrings: []string{},
},
{
description: "namespace 2",
namespaces: []Namespace{"ns1", "ns2"},
description: "2 namespaces",
namespaces: []contourv1.Namespace{"ns1", "ns2"},
expectStrings: []string{"ns1", "ns2"},
},
}
Expand All @@ -44,3 +46,30 @@ func TestNamespacesToStrings(t *testing.T) {
})
}
}

func TestFeaturesToStrings(t *testing.T) {
testCases := []struct {
description string
features []contourv1.Feature
expectStrings []string
}{
{
description: "no features",
features: []contourv1.Feature{},
expectStrings: []string{},
},
{
description: "2 features",
features: []contourv1.Feature{"tlsroutes", "grpcroutes"},
expectStrings: []string{"tlsroutes", "grpcroutes"},
},
}

for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
if !reflect.DeepEqual(FeaturesToStrings(tc.features), tc.expectStrings) {
t.Errorf("expect converted strings %v is the same as %v", FeaturesToStrings(tc.features), tc.expectStrings)
}
})
}
}
8 changes: 6 additions & 2 deletions internal/provisioner/objects/deployment/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,17 @@ func DesiredDeployment(contour *model.Contour, image string) *appsv1.Deployment
}

if !contour.WatchAllNamespaces() {
ns := contour.Spec.WatchNamespaces
if !slices.Contains(contour.Spec.WatchNamespaces, contour.Namespace) {
ns := model.NamespacesToStrings(contour.Spec.WatchNamespaces)
if !slices.Contains(ns, contour.Namespace) {
ns = append(ns, contour.Namespace)
}
args = append(args, fmt.Sprintf("--watch-namespaces=%s", strings.Join(ns, ",")))
}

if contour.Spec.DisabledFeatures != nil && len(contour.Spec.DisabledFeatures) > 0 {
args = append(args, fmt.Sprintf("--disable-feature=%s", strings.Join(model.FeaturesToStrings(contour.Spec.DisabledFeatures), ",")))
}

// Pass the insecure/secure flags to Contour if using non-default ports.
for _, port := range contour.Spec.NetworkPublishing.Envoy.Ports {
switch {
Expand Down
40 changes: 36 additions & 4 deletions internal/provisioner/objects/deployment/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"strings"
"testing"

contourv1 "github.com/projectcontour/contour/apis/projectcontour/v1"
"github.com/projectcontour/contour/apis/projectcontour/v1alpha1"
"github.com/projectcontour/contour/internal/provisioner/model"

Expand Down Expand Up @@ -216,15 +217,15 @@ func TestDesiredDeployment(t *testing.T) {
func TestDesiredDeploymentWhenSettingWatchNamespaces(t *testing.T) {
testCases := []struct {
description string
namespaces []string
namespaces []contourv1.Namespace
}{
{
description: "several valid namespaces",
namespaces: []string{"ns1", "ns2"},
namespaces: []contourv1.Namespace{"ns1", "ns2"},
},
{
description: "single valid namespace",
namespaces: []string{"ns1"},
namespaces: []contourv1.Namespace{"ns1"},
},
}

Expand All @@ -238,7 +239,7 @@ func TestDesiredDeploymentWhenSettingWatchNamespaces(t *testing.T) {
cntr.Spec.WatchNamespaces = tc.namespaces
deploy := DesiredDeployment(cntr, "ghcr.io/projectcontour/contour:test")
container := checkDeploymentHasContainer(t, deploy, contourContainerName, true)
arg := fmt.Sprintf("--watch-namespaces=%s", strings.Join(append(tc.namespaces, cntr.Namespace), ","))
arg := fmt.Sprintf("--watch-namespaces=%s", strings.Join(append(model.NamespacesToStrings(tc.namespaces), cntr.Namespace), ","))
checkContainerHasArg(t, container, arg)
})
}
Expand Down Expand Up @@ -270,3 +271,34 @@ func TestNodePlacementDeployment(t *testing.T) {
checkDeploymentHasNodeSelector(t, deploy, selectors)
checkDeploymentHasTolerations(t, deploy, tolerations)
}

func TestDesiredDeploymentWhenSettingDisabledFeature(t *testing.T) {
testCases := []struct {
description string
disabledFeatures []contourv1.Feature
}{
{
description: "disable 2 featuers",
disabledFeatures: []contourv1.Feature{"tlsroutes", "grpcroutes"},
},
{
description: "disable single feature",
disabledFeatures: []contourv1.Feature{"tlsroutes"},
},
}

for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
name := "deploy-test"
cntr := model.Default(fmt.Sprintf("%s-ns", name), name)
icName := "test-ic"
cntr.Spec.IngressClassName = &icName
cntr.Spec.DisabledFeatures = tc.disabledFeatures
// Change the Contour watch namespaces flag
deploy := DesiredDeployment(cntr, "ghcr.io/projectcontour/contour:test")
container := checkDeploymentHasContainer(t, deploy, contourContainerName, true)
arg := fmt.Sprintf("--disable-feature=%s", strings.Join(model.FeaturesToStrings(tc.disabledFeatures), ","))
checkContainerHasArg(t, container, arg)
})
}
}
4 changes: 2 additions & 2 deletions internal/provisioner/objects/rbac/clusterrole/cluster_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ func desiredClusterRole(name string, contour *model.Contour, clusterScopedResour
return role
}

// add basic rules to role
role.Rules = append(role.Rules, util.NamespacedResourcePolicyRules()...)
// add other rules for namespacedResources, so that we can associated them with ClusterRole later
role.Rules = append(role.Rules, util.NamespacedResourcePolicyRules(contour.Spec.DisabledFeatures)...)
return role
}

Expand Down
Loading

0 comments on commit 39a7d20

Please sign in to comment.