Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow gatewayProvisioner to create contour that only watch limited na… #6073

Merged
merged 12 commits into from
Jan 30, 2024
21 changes: 21 additions & 0 deletions apis/projectcontour/v1/httpproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,27 @@ type HTTPProxySpec struct {
IngressClassName string `json:"ingressClassName,omitempty"`
}

// Namespace refers to a Kubernetes namespace. It must be a RFC 1123 label.
//
// This validation is based off of the corresponding Kubernetes validation:
// https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L187
//
// This is used for Namespace name validation here:
// https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/api/validation/generic.go#L63
//
// Valid values include:
//
// * "example"
//
// Invalid values include:
//
// * "example.com" - "." is an invalid character
//
// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=63
type Namespace string

// Include describes a set of policies that can be applied to an HTTPProxy in a namespace.
type Include struct {
// Name of the HTTPProxy
Expand Down
22 changes: 22 additions & 0 deletions apis/projectcontour/v1/httpproxy_helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright Project Contour Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package v1

func NamespacesToStrings(ns []Namespace) []string {
res := make([]string, len(ns))
for i, n := range ns {
res[i] = string(n)
}
return res
}
46 changes: 46 additions & 0 deletions apis/projectcontour/v1/httpproxy_helpers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright Project Contour Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package v1

import (
"reflect"
"testing"
)

func TestNamespacesToStrings(t *testing.T) {
testCases := []struct {
description string
namespaces []Namespace
expectStrings []string
}{
{
description: "namespace 1",
namespaces: []Namespace{},
expectStrings: []string{},
},
{
description: "namespace 2",
namespaces: []Namespace{"ns1", "ns2"},
expectStrings: []string{"ns1", "ns2"},
},
}

for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
if !reflect.DeepEqual(NamespacesToStrings(tc.namespaces), tc.expectStrings) {
t.Errorf("expect converted strings %v is the same as %v", NamespacesToStrings(tc.namespaces), tc.expectStrings)
}
})
}
}
9 changes: 9 additions & 0 deletions apis/projectcontour/v1alpha1/contourdeployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package v1alpha1

import (
contour_api_v1 "github.com/projectcontour/contour/apis/projectcontour/v1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -122,6 +123,14 @@ type ContourSettings struct {
// the annotations for Prometheus will be appended or overwritten with predefined value.
// +optional
PodAnnotations map[string]string `json:"podAnnotations,omitempty"`

// WatchNamespaces is an array of namespaces. Setting it will instruct the contour instance
// to only watch this subset of namespaces.
// +optional
// +kubebuilder:validation:Type=array
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=42
WatchNamespaces []contour_api_v1.Namespace `json:"watchNamespaces,omitempty"`
}

// DeploymentSettings contains settings for Deployment resources.
Expand Down
5 changes: 5 additions & 0 deletions apis/projectcontour/v1alpha1/zz_generated.deepcopy.go

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

1 change: 1 addition & 0 deletions changelogs/unreleased/6073-lubronzhan-small.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Allow gatewayProvisioner to create contour that only watch limited namespaces of resources
22 changes: 22 additions & 0 deletions examples/contour/01-crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1620,6 +1620,28 @@ spec:
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
type: object
type: object
watchNamespaces:
description: |-
WatchNamespaces is an array of namespaces. Setting it will instruct the contour instance
to only watch this subset of namespaces.
items:
description: |-
Namespace refers to a Kubernetes namespace. It must be a RFC 1123 label.
This validation is based off of the corresponding Kubernetes validation:
https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L187
This is used for Namespace name validation here:
https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/api/validation/generic.go#L63
Valid values include:
* "example"
Invalid values include:
* "example.com" - "." is an invalid character
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
maxItems: 42
minItems: 1
type: array
type: object
envoy:
description: |-
Expand Down
22 changes: 22 additions & 0 deletions examples/render/contour-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1839,6 +1839,28 @@ spec:
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
type: object
type: object
watchNamespaces:
description: |-
WatchNamespaces is an array of namespaces. Setting it will instruct the contour instance
to only watch this subset of namespaces.
items:
description: |-
Namespace refers to a Kubernetes namespace. It must be a RFC 1123 label.
This validation is based off of the corresponding Kubernetes validation:
https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L187
This is used for Namespace name validation here:
https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/api/validation/generic.go#L63
Valid values include:
* "example"
Invalid values include:
* "example.com" - "." is an invalid character
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
maxItems: 42
minItems: 1
type: array
type: object
envoy:
description: |-
Expand Down
22 changes: 22 additions & 0 deletions examples/render/contour-gateway-provisioner.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1631,6 +1631,28 @@ spec:
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
type: object
type: object
watchNamespaces:
description: |-
WatchNamespaces is an array of namespaces. Setting it will instruct the contour instance
to only watch this subset of namespaces.
items:
description: |-
Namespace refers to a Kubernetes namespace. It must be a RFC 1123 label.
This validation is based off of the corresponding Kubernetes validation:
https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L187
This is used for Namespace name validation here:
https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/api/validation/generic.go#L63
Valid values include:
* "example"
Invalid values include:
* "example.com" - "." is an invalid character
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
maxItems: 42
minItems: 1
type: array
type: object
envoy:
description: |-
Expand Down
22 changes: 22 additions & 0 deletions examples/render/contour-gateway.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1842,6 +1842,28 @@ spec:
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
type: object
type: object
watchNamespaces:
description: |-
WatchNamespaces is an array of namespaces. Setting it will instruct the contour instance
to only watch this subset of namespaces.
items:
description: |-
Namespace refers to a Kubernetes namespace. It must be a RFC 1123 label.
This validation is based off of the corresponding Kubernetes validation:
https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L187
This is used for Namespace name validation here:
https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/api/validation/generic.go#L63
Valid values include:
* "example"
Invalid values include:
* "example.com" - "." is an invalid character
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
maxItems: 42
minItems: 1
type: array
type: object
envoy:
description: |-
Expand Down
22 changes: 22 additions & 0 deletions examples/render/contour.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1839,6 +1839,28 @@ spec:
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
type: object
type: object
watchNamespaces:
description: |-
WatchNamespaces is an array of namespaces. Setting it will instruct the contour instance
to only watch this subset of namespaces.
items:
description: |-
Namespace refers to a Kubernetes namespace. It must be a RFC 1123 label.
This validation is based off of the corresponding Kubernetes validation:
https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L187
This is used for Namespace name validation here:
https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/api/validation/generic.go#L63
Valid values include:
* "example"
Invalid values include:
* "example.com" - "." is an invalid character
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
maxItems: 42
minItems: 1
type: array
type: object
envoy:
description: |-
Expand Down
4 changes: 0 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,6 @@ github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0X
github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA=
github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
Expand Down Expand Up @@ -381,8 +379,6 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/tsaarni/certyaml v0.9.2 h1:LoRTuajwjJ1CHAJiMv5cpOtwQ05207Oqe6cT9D7WDaQ=
github.com/tsaarni/certyaml v0.9.2/go.mod h1:s+ErAC1wZ32r1ihSULvR7HXedKKN5HZasdb8Cj8gT9E=
github.com/tsaarni/certyaml v0.9.3 h1:m8HHbuUzWVUOmv8IQU9HgVZZ8r5ICExKm++54DJKCs0=
github.com/tsaarni/certyaml v0.9.3/go.mod h1:hhuU1qYr5re488geArUP4gZWqMUMqGlj4HA2qUyGYLk=
github.com/tsaarni/x500dn v1.0.0 h1:LvaWTkqRpse4VHBhB5uwf3wytokK4vF9IOyNAEyiA+U=
Expand Down
3 changes: 3 additions & 0 deletions internal/provisioner/controller/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ 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 @@ -261,6 +262,8 @@ 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)

if contourParams.Deployment != nil &&
contourParams.Deployment.Strategy != nil {
contourModel.Spec.ContourDeploymentStrategy = *contourParams.Deployment.Strategy
Expand Down
9 changes: 9 additions & 0 deletions internal/provisioner/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ func (c *Contour) EnvoyTolerationsExist() bool {
return false
}

func (c *Contour) WatchAllNamespaces() bool {
return c.Spec.WatchNamespaces == nil || len(c.Spec.WatchNamespaces) == 0
}

// ContourSpec defines the desired state of Contour.
type ContourSpec struct {
// ContourReplicas is the desired number of Contour replicas. If unset,
Expand Down Expand Up @@ -245,6 +249,11 @@ type ContourSpec struct {
// If the value is 0, the overload manager is disabled.
// defaults to 0.
EnvoyMaxHeapSizeBytes uint64

// 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
}

// WorkloadType is the type of Kubernetes workload to use for a component.
Expand Down
16 changes: 10 additions & 6 deletions internal/provisioner/model/names.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ func (c *Contour) ContourRBACNames() RBACNames {
Role: fmt.Sprintf("contour-%s", c.Name),

// this one has a different prefix to differentiate from the certgen role binding (see below).
RoleBinding: fmt.Sprintf("contour-rolebinding-%s", c.Name),
RoleBinding: fmt.Sprintf("contour-rolebinding-%s", c.Name),
NamespaceScopedResourceRole: fmt.Sprintf("contour-resources-%s-%s", c.Namespace, c.Name),
NamespaceScopedResourceRoleBinding: fmt.Sprintf("contour-resources-%s-%s", c.Namespace, c.Name),
}
}

Expand Down Expand Up @@ -129,9 +131,11 @@ func (c *Contour) CommonAnnotations() map[string]string {

// RBACNames holds a set of names of related RBAC resources.
type RBACNames struct {
ServiceAccount string
ClusterRole string
ClusterRoleBinding string
Role string
RoleBinding string
ServiceAccount string
ClusterRole string
ClusterRoleBinding string
Role string
RoleBinding string
NamespaceScopedResourceRole string
NamespaceScopedResourceRoleBinding string
}
10 changes: 10 additions & 0 deletions internal/provisioner/objects/deployment/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import (
"context"
"fmt"
"path/filepath"
"slices"
"strings"

"github.com/projectcontour/contour/apis/projectcontour/v1alpha1"
"github.com/projectcontour/contour/internal/provisioner/equality"
Expand Down Expand Up @@ -100,6 +102,14 @@ func DesiredDeployment(contour *model.Contour, image string) *appsv1.Deployment
args = append(args, "--debug")
}

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

// Pass the insecure/secure flags to Contour if using non-default ports.
for _, port := range contour.Spec.NetworkPublishing.Envoy.Ports {
switch {
Expand Down
Loading
Loading