Skip to content

Commit

Permalink
crd/ContourDeployment: Add fields 'extraVolumes & extraVolumeMounts' (#…
Browse files Browse the repository at this point in the history
…4680)

Signed-off-by: Gang Liu <gang.liu@daocloud.io>
  • Loading branch information
izturn authored Oct 13, 2022
1 parent 271edab commit 0467b84
Show file tree
Hide file tree
Showing 16 changed files with 8,151 additions and 2 deletions.
1 change: 1 addition & 0 deletions apis/projectcontour/v1alpha1/contourconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ package v1alpha1

import (
contour_api_v1 "github.com/projectcontour/contour/apis/projectcontour/v1"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down
8 changes: 8 additions & 0 deletions apis/projectcontour/v1alpha1/contourdeployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ type EnvoySettings struct {
//
// +optional
NodePlacement *NodePlacement `json:"nodePlacement,omitempty"`

// ExtraVolumes holds the extra volumes to add.
// +optional
ExtraVolumes []corev1.Volume `json:"extraVolumes,omitempty"`

// ExtraVolumeMounts holds the extra volume mounts to add (normally used with extraVolumes).
// +optional
ExtraVolumeMounts []corev1.VolumeMount `json:"extraVolumeMounts,omitempty"`
}

// WorkloadType is the type of Kubernetes workload to use for a component.
Expand Down
14 changes: 14 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/4680-izturn-small.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add the fields extraVolumes & extraVolumeMounts to crd/ContourDeployment to enable Envoy pods to mount additional volumes
1,596 changes: 1,596 additions & 0 deletions examples/contour/01-crds.yaml

Large diffs are not rendered by default.

1,596 changes: 1,596 additions & 0 deletions examples/render/contour-deployment.yaml

Large diffs are not rendered by default.

1,596 changes: 1,596 additions & 0 deletions examples/render/contour-gateway-provisioner.yaml

Large diffs are not rendered by default.

1,596 changes: 1,596 additions & 0 deletions examples/render/contour-gateway.yaml

Large diffs are not rendered by default.

1,596 changes: 1,596 additions & 0 deletions examples/render/contour.yaml

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions internal/provisioner/controller/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,11 @@ func (r *gatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
Tolerations: nodePlacement.Tolerations,
}
}

// volume mount
contourModel.Spec.EnvoyExtraVolumeMounts = append(contourModel.Spec.EnvoyExtraVolumeMounts, gatewayClassParams.Spec.Envoy.ExtraVolumeMounts...)
contourModel.Spec.EnvoyExtraVolumes = append(contourModel.Spec.EnvoyExtraVolumes, gatewayClassParams.Spec.Envoy.ExtraVolumes...)

}
}

Expand Down
13 changes: 13 additions & 0 deletions internal/provisioner/controller/gatewayclass.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,19 @@ func (r *gatewayClassReconciler) Reconcile(ctx context.Context, req ctrl.Request
invalidParamsMessages = append(invalidParamsMessages, msg)
}
}

if params.Spec.Envoy.ExtraVolumeMounts != nil {
volumes := map[string]struct{}{}
for _, vol := range params.Spec.Envoy.ExtraVolumes {
volumes[vol.Name] = struct{}{}
}
for _, mnt := range params.Spec.Envoy.ExtraVolumeMounts {
if _, ok := volumes[mnt.Name]; !ok {
msg := fmt.Sprintf("invalid ContourDeployment spec.envoy.extraVolumeMounts, mount to unknown volume: %q", mnt.Name)
invalidParamsMessages = append(invalidParamsMessages, msg)
}
}
}
}

if len(invalidParamsMessages) > 0 {
Expand Down
47 changes: 45 additions & 2 deletions internal/provisioner/controller/gatewayclass_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ import (
"context"
"testing"

"github.com/go-logr/logr"
contourv1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1"
"github.com/projectcontour/contour/internal/gatewayapi"
"github.com/projectcontour/contour/internal/provisioner"

"github.com/go-logr/logr"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -240,7 +242,7 @@ func TestGatewayClassReconcile(t *testing.T) {
Reason: string(gatewayv1beta1.GatewayClassReasonAccepted),
},
},
"gatewayclass controlled by us with a valid parametersRef but invalid parameter values gets Accepted: false condition": {
"gatewayclass controlled by us with a valid parametersRef but invalid parameter values for NetworkPublishing gets Accepted: false condition": {
gatewayClass: &gatewayv1beta1.GatewayClass{
ObjectMeta: metav1.ObjectMeta{
Name: "gatewayclass-1",
Expand Down Expand Up @@ -275,6 +277,47 @@ func TestGatewayClassReconcile(t *testing.T) {
Reason: string(gatewayv1beta1.GatewayClassReasonInvalidParameters),
},
},
"gatewayclass controlled by us with a valid parametersRef but invalid parameter values for ExtraVolumeMounts 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{
ExtraVolumeMounts: []corev1.VolumeMount{
{
Name: "volume-a",
},
},
ExtraVolumes: []corev1.Volume{
{
Name: "volume-b",
},
},
},
},
},
wantCondition: &metav1.Condition{
Type: string(gatewayv1beta1.GatewayClassConditionStatusAccepted),
Status: metav1.ConditionFalse,
Reason: string(gatewayv1beta1.GatewayClassReasonInvalidParameters),
},
},
}

for name, tc := range tests {
Expand Down
6 changes: 6 additions & 0 deletions internal/provisioner/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ type ContourSpec struct {

// ResourceLabels is a set of labels to add to the provisioned Contour resource(s).
ResourceLabels map[string]string

// EnvoyExtraVolumes holds the extra volumes to add to envoy's pod.
EnvoyExtraVolumes []corev1.Volume

// EnvoyExtraVolumeMounts holds the extra volume mounts to add to envoy's pod(normally used with envoyExtraVolumes).
EnvoyExtraVolumeMounts []corev1.VolumeMount
}

// WorkloadType is the type of Kubernetes workload to use for a component.
Expand Down
7 changes: 7 additions & 0 deletions internal/provisioner/objects/dataplane/dataplane.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,9 @@ func desiredContainers(contour *model.Contour, contourImage, envoyImage string)
},
}

for j := range containers {
containers[j].VolumeMounts = append(containers[j].VolumeMounts, contour.Spec.EnvoyExtraVolumeMounts...)
}
return initContainers, containers
}

Expand Down Expand Up @@ -380,6 +383,8 @@ func DesiredDaemonSet(contour *model.Contour, contourImage, envoyImage string) *
},
}

ds.Spec.Template.Spec.Volumes = append(ds.Spec.Template.Spec.Volumes, contour.Spec.EnvoyExtraVolumes...)

if contour.EnvoyNodeSelectorExists() {
ds.Spec.Template.Spec.NodeSelector = contour.Spec.NodePlacement.Envoy.NodeSelector
}
Expand Down Expand Up @@ -462,6 +467,8 @@ func desiredDeployment(contour *model.Contour, contourImage, envoyImage string)
},
}

deployment.Spec.Template.Spec.Volumes = append(deployment.Spec.Template.Spec.Volumes, contour.Spec.EnvoyExtraVolumes...)

if contour.EnvoyNodeSelectorExists() {
deployment.Spec.Template.Spec.NodeSelector = contour.Spec.NodePlacement.Envoy.NodeSelector
}
Expand Down
41 changes: 41 additions & 0 deletions internal/provisioner/objects/dataplane/dataplane_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,36 @@ func checkDaemonSetHasNodeSelector(t *testing.T, ds *appsv1.DaemonSet, expected
t.Errorf("deployment has unexpected node selector %q", expected)
}

func checkDaemonSetHasVolume(t *testing.T, ds *appsv1.DaemonSet, vol corev1.Volume, volMount corev1.VolumeMount) {
t.Helper()

hasVol := false
hasVolMount := false

for _, v := range ds.Spec.Template.Spec.Volumes {
if v.Name == vol.Name {
hasVol = true
if !apiequality.Semantic.DeepEqual(v, vol) {
t.Errorf("daemonset has unexpected volume %q", vol)
}
}
}

for _, v := range ds.Spec.Template.Spec.Containers[0].VolumeMounts {
if v.Name == volMount.Name {
hasVolMount = true
if !apiequality.Semantic.DeepEqual(v, volMount) {
t.Errorf("daemonset has unexpected volume mount %q", vol)
}
}
}

if !(hasVol && hasVolMount) {
t.Errorf("daemonset has not found volume or volumeMount")
}

}

func checkDaemonSetHasTolerations(t *testing.T, ds *appsv1.DaemonSet, expected []corev1.Toleration) {
t.Helper()

Expand Down Expand Up @@ -158,6 +188,16 @@ func TestDesiredDaemonSet(t *testing.T) {
"key": "val",
}

volTest := corev1.Volume{
Name: "vol-test-mount",
}
volTestMount := corev1.VolumeMount{
Name: volTest.Name,
}

cntr.Spec.EnvoyExtraVolumes = append(cntr.Spec.EnvoyExtraVolumes, volTest)
cntr.Spec.EnvoyExtraVolumeMounts = append(cntr.Spec.EnvoyExtraVolumeMounts, volTestMount)

testContourImage := "ghcr.io/projectcontour/contour:test"
testEnvoyImage := "docker.io/envoyproxy/envoy:test"
ds := DesiredDaemonSet(cntr, testContourImage, testEnvoyImage)
Expand All @@ -177,6 +217,7 @@ func TestDesiredDaemonSet(t *testing.T) {
checkDaemonSetHasNodeSelector(t, ds, nil)
checkDaemonSetHasTolerations(t, ds, nil)
checkDaemonSecurityContext(t, ds)
checkDaemonSetHasVolume(t, ds, volTest, volTestMount)
}

func TestNodePlacementDaemonSet(t *testing.T) {
Expand Down
30 changes: 30 additions & 0 deletions site/content/docs/main/config/api-reference.html
Original file line number Diff line number Diff line change
Expand Up @@ -5866,6 +5866,36 @@ <h3 id="projectcontour.io/v1alpha1.EnvoySettings">EnvoySettings
<p>NodePlacement describes node scheduling configuration of Envoy pods.</p>
</td>
</tr>
<tr>
<td style="white-space:nowrap">
<code>extraVolumes</code>
<br>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#volume-v1-core">
[]Kubernetes core/v1.Volume
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>ExtraVolumes holds the extra volumes to add.</p>
</td>
</tr>
<tr>
<td style="white-space:nowrap">
<code>extraVolumeMounts</code>
<br>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#volumemount-v1-core">
[]Kubernetes core/v1.VolumeMount
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>ExtraVolumeMounts holds the extra volume mounts to add (normally used with extraVolumes).</p>
</td>
</tr>
</tbody>
</table>
<h3 id="projectcontour.io/v1alpha1.EnvoyTLS">EnvoyTLS
Expand Down

0 comments on commit 0467b84

Please sign in to comment.