Skip to content

Commit d8d168a

Browse files
authored
Merge branch 'main' into tests/nfr-tests-edge
2 parents 7f5dbb7 + 3068c6e commit d8d168a

File tree

14 files changed

+459
-28
lines changed

14 files changed

+459
-28
lines changed

charts/nginx-gateway-fabric/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,11 @@ The following table lists the configurable parameters of the NGINX Gateway Fabri
195195
196196
| Key | Description | Type | Default |
197197
|-----|-------------|------|---------|
198-
| `certGenerator` | The certGenerator section contains the configuration for the cert-generator Job. | object | `{"affinity":{},"agentTLSSecretName":"agent-tls","annotations":{},"nodeSelector":{},"overwrite":false,"serverTLSSecretName":"server-tls","tolerations":[],"topologySpreadConstraints":[],"ttlSecondsAfterFinished":30}` |
198+
| `certGenerator` | The certGenerator section contains the configuration for the cert-generator Job. | object | `{"affinity":{},"agentTLSSecretName":"agent-tls","annotations":{},"enable":true,"nodeSelector":{},"overwrite":false,"serverTLSSecretName":"server-tls","tolerations":[],"topologySpreadConstraints":[],"ttlSecondsAfterFinished":30}` |
199199
| `certGenerator.affinity` | The affinity of the cert-generator pod. | object | `{}` |
200200
| `certGenerator.agentTLSSecretName` | The name of the base Secret containing TLS CA, certificate, and key for the NGINX Agent to securely communicate with the NGINX Gateway Fabric control plane. Must exist in the same namespace that the NGINX Gateway Fabric control plane is running in (default namespace: nginx-gateway). | string | `"agent-tls"` |
201201
| `certGenerator.annotations` | The annotations of the cert-generator Job. | object | `{}` |
202+
| `certGenerator.enable` | Enable the cert-generator Job. If this is disabled, then cert-manager or some other method must be used to create the required Secrets. | bool | `true` |
202203
| `certGenerator.nodeSelector` | The nodeSelector of the cert-generator pod. | object | `{}` |
203204
| `certGenerator.overwrite` | Overwrite existing TLS Secrets on startup. | bool | `false` |
204205
| `certGenerator.serverTLSSecretName` | The name of the Secret containing TLS CA, certificate, and key for the NGINX Gateway Fabric control plane to securely communicate with the NGINX Agent. Must exist in the same namespace that the NGINX Gateway Fabric control plane is running in (default namespace: nginx-gateway). | string | `"server-tls"` |

charts/nginx-gateway-fabric/templates/certs-job.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{{- if .Values.certGenerator.enable }}
12
apiVersion: v1
23
kind: ServiceAccount
34
metadata:
@@ -172,3 +173,4 @@ spec:
172173
{{- toYaml .Values.certGenerator.nodeSelector | nindent 8 }}
173174
{{- end }}
174175
ttlSecondsAfterFinished: {{ .Values.certGenerator.ttlSecondsAfterFinished }}
176+
{{- end }}

charts/nginx-gateway-fabric/values.schema.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@
2323
"title": "annotations",
2424
"type": "object"
2525
},
26+
"enable": {
27+
"default": true,
28+
"description": "Enable the cert-generator Job. If this is disabled, then cert-manager or some other method must be used to create the required Secrets.",
29+
"required": [],
30+
"title": "enable",
31+
"type": "boolean"
32+
},
2633
"nodeSelector": {
2734
"description": "The nodeSelector of the cert-generator pod.",
2835
"required": [],

charts/nginx-gateway-fabric/values.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,8 @@ nginx:
672672

673673
# -- The certGenerator section contains the configuration for the cert-generator Job.
674674
certGenerator:
675+
# -- Enable the cert-generator Job. If this is disabled, then cert-manager or some other method must be used to create the required Secrets.
676+
enable: true
675677
# -- The annotations of the cert-generator Job.
676678
annotations: {}
677679

internal/controller/handler.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,20 @@ func (h *eventHandlerImpl) sendNginxConfig(ctx context.Context, logger logr.Logg
241241

242242
h.setLatestConfiguration(gw, &cfg)
243243

244+
vm := []v1.VolumeMount{}
245+
if gw.EffectiveNginxProxy != nil &&
246+
gw.EffectiveNginxProxy.Kubernetes != nil {
247+
if gw.EffectiveNginxProxy.Kubernetes.Deployment != nil {
248+
vm = gw.EffectiveNginxProxy.Kubernetes.Deployment.Container.VolumeMounts
249+
}
250+
251+
if gw.EffectiveNginxProxy.Kubernetes.DaemonSet != nil {
252+
vm = gw.EffectiveNginxProxy.Kubernetes.DaemonSet.Container.VolumeMounts
253+
}
254+
}
255+
244256
deployment.FileLock.Lock()
245-
h.updateNginxConf(deployment, cfg)
257+
h.updateNginxConf(deployment, cfg, vm)
246258
deployment.FileLock.Unlock()
247259

248260
configErr := deployment.GetLatestConfigError()
@@ -454,9 +466,10 @@ func (h *eventHandlerImpl) parseAndCaptureEvent(ctx context.Context, logger logr
454466
func (h *eventHandlerImpl) updateNginxConf(
455467
deployment *agent.Deployment,
456468
conf dataplane.Configuration,
469+
volumeMounts []v1.VolumeMount,
457470
) {
458471
files := h.cfg.generator.Generate(conf)
459-
h.cfg.nginxUpdater.UpdateConfig(deployment, files)
472+
h.cfg.nginxUpdater.UpdateConfig(deployment, files, volumeMounts)
460473

461474
// If using NGINX Plus, update upstream servers using the API.
462475
if h.cfg.plus {

internal/controller/handler_test.go

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
2323

2424
ngfAPI "github.com/nginx/nginx-gateway-fabric/v2/apis/v1alpha1"
25+
"github.com/nginx/nginx-gateway-fabric/v2/apis/v1alpha2"
2526
"github.com/nginx/nginx-gateway-fabric/v2/internal/controller/config"
2627
"github.com/nginx/nginx-gateway-fabric/v2/internal/controller/licensing/licensingfakes"
2728
"github.com/nginx/nginx-gateway-fabric/v2/internal/controller/metrics/collectors"
@@ -66,7 +67,7 @@ var _ = Describe("eventHandler", func() {
6667
Expect(fakeGenerator.GenerateArgsForCall(0)).Should(Equal(expectedConf))
6768

6869
Expect(fakeNginxUpdater.UpdateConfigCallCount()).Should(Equal(1))
69-
_, files := fakeNginxUpdater.UpdateConfigArgsForCall(0)
70+
_, files, _ := fakeNginxUpdater.UpdateConfigArgsForCall(0)
7071
Expect(expectedFiles).To(Equal(files))
7172

7273
Eventually(
@@ -642,6 +643,104 @@ var _ = Describe("eventHandler", func() {
642643

643644
Expect(handler.GetLatestConfiguration()).To(BeEmpty())
644645
})
646+
647+
It("should process events with volume mounts from Deployment", func() {
648+
// Create a gateway with EffectiveNginxProxy containing Deployment VolumeMounts
649+
gatewayWithVolumeMounts := &graph.Graph{
650+
Gateways: map[types.NamespacedName]*graph.Gateway{
651+
{Namespace: "test", Name: "gateway"}: {
652+
Valid: true,
653+
Source: &gatewayv1.Gateway{
654+
ObjectMeta: metav1.ObjectMeta{
655+
Name: "gateway",
656+
Namespace: "test",
657+
},
658+
},
659+
DeploymentName: types.NamespacedName{
660+
Namespace: "test",
661+
Name: controller.CreateNginxResourceName("gateway", "nginx"),
662+
},
663+
EffectiveNginxProxy: &graph.EffectiveNginxProxy{
664+
Kubernetes: &v1alpha2.KubernetesSpec{
665+
Deployment: &v1alpha2.DeploymentSpec{
666+
Container: v1alpha2.ContainerSpec{
667+
VolumeMounts: []v1.VolumeMount{
668+
{
669+
Name: "test-volume",
670+
MountPath: "/etc/test",
671+
},
672+
},
673+
},
674+
},
675+
},
676+
},
677+
},
678+
},
679+
}
680+
681+
fakeProcessor.ProcessReturns(gatewayWithVolumeMounts)
682+
683+
e := &events.UpsertEvent{Resource: &gatewayv1.HTTPRoute{}}
684+
batch := []interface{}{e}
685+
686+
handler.HandleEventBatch(context.Background(), logr.Discard(), batch)
687+
688+
// Verify that UpdateConfig was called with the volume mounts
689+
Expect(fakeNginxUpdater.UpdateConfigCallCount()).Should(Equal(1))
690+
_, _, volumeMounts := fakeNginxUpdater.UpdateConfigArgsForCall(0)
691+
Expect(volumeMounts).To(HaveLen(1))
692+
Expect(volumeMounts[0].Name).To(Equal("test-volume"))
693+
Expect(volumeMounts[0].MountPath).To(Equal("/etc/test"))
694+
})
695+
696+
It("should process events with volume mounts from DaemonSet", func() {
697+
// Create a gateway with EffectiveNginxProxy containing DaemonSet VolumeMounts
698+
gatewayWithVolumeMounts := &graph.Graph{
699+
Gateways: map[types.NamespacedName]*graph.Gateway{
700+
{Namespace: "test", Name: "gateway"}: {
701+
Valid: true,
702+
Source: &gatewayv1.Gateway{
703+
ObjectMeta: metav1.ObjectMeta{
704+
Name: "gateway",
705+
Namespace: "test",
706+
},
707+
},
708+
DeploymentName: types.NamespacedName{
709+
Namespace: "test",
710+
Name: controller.CreateNginxResourceName("gateway", "nginx"),
711+
},
712+
EffectiveNginxProxy: &graph.EffectiveNginxProxy{
713+
Kubernetes: &v1alpha2.KubernetesSpec{
714+
DaemonSet: &v1alpha2.DaemonSetSpec{
715+
Container: v1alpha2.ContainerSpec{
716+
VolumeMounts: []v1.VolumeMount{
717+
{
718+
Name: "daemon-volume",
719+
MountPath: "/var/daemon",
720+
},
721+
},
722+
},
723+
},
724+
},
725+
},
726+
},
727+
},
728+
}
729+
730+
fakeProcessor.ProcessReturns(gatewayWithVolumeMounts)
731+
732+
e := &events.UpsertEvent{Resource: &gatewayv1.HTTPRoute{}}
733+
batch := []interface{}{e}
734+
735+
handler.HandleEventBatch(context.Background(), logr.Discard(), batch)
736+
737+
// Verify that UpdateConfig was called with the volume mounts
738+
Expect(fakeNginxUpdater.UpdateConfigCallCount()).Should(Equal(1))
739+
_, _, volumeMounts := fakeNginxUpdater.UpdateConfigArgsForCall(0)
740+
Expect(volumeMounts).To(HaveLen(1))
741+
Expect(volumeMounts[0].Name).To(Equal("daemon-volume"))
742+
Expect(volumeMounts[0].MountPath).To(Equal("/var/daemon"))
743+
})
645744
})
646745

647746
var _ = Describe("getGatewayAddresses", func() {

internal/controller/nginx/agent/agent.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/go-logr/logr"
1111
pb "github.com/nginx/agent/v3/api/grpc/mpi/v1"
1212
"google.golang.org/protobuf/types/known/structpb"
13+
v1 "k8s.io/api/core/v1"
1314
"k8s.io/apimachinery/pkg/util/wait"
1415
"sigs.k8s.io/controller-runtime/pkg/client"
1516

@@ -29,7 +30,7 @@ const retryUpstreamTimeout = 5 * time.Second
2930

3031
// NginxUpdater is an interface for updating NGINX using the NGINX agent.
3132
type NginxUpdater interface {
32-
UpdateConfig(deployment *Deployment, files []File)
33+
UpdateConfig(deployment *Deployment, files []File, volumeMounts []v1.VolumeMount)
3334
UpdateUpstreamServers(deployment *Deployment, conf dataplane.Configuration)
3435
}
3536

@@ -87,8 +88,9 @@ func NewNginxUpdater(
8788
func (n *NginxUpdaterImpl) UpdateConfig(
8889
deployment *Deployment,
8990
files []File,
91+
volumeMounts []v1.VolumeMount,
9092
) {
91-
msg := deployment.SetFiles(files)
93+
msg := deployment.SetFiles(files, volumeMounts)
9294
if msg == nil {
9395
n.logger.V(1).Info("No changes to nginx configuration files, not sending to agent")
9496
return

internal/controller/nginx/agent/agent_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
pb "github.com/nginx/agent/v3/api/grpc/mpi/v1"
1010
. "github.com/onsi/gomega"
1111
"google.golang.org/protobuf/types/known/structpb"
12+
v1 "k8s.io/api/core/v1"
1213
"sigs.k8s.io/controller-runtime/pkg/client/fake"
1314

1415
"github.com/nginx/nginx-gateway-fabric/v2/internal/controller/nginx/agent/broadcast/broadcastfakes"
@@ -63,7 +64,7 @@ func TestUpdateConfig(t *testing.T) {
6364
deployment.SetPodErrorStatus("pod1", testErr)
6465
}
6566

66-
updater.UpdateConfig(deployment, []File{file})
67+
updater.UpdateConfig(deployment, []File{file}, []v1.VolumeMount{})
6768

6869
g.Expect(fakeBroadcaster.SendCallCount()).To(Equal(1))
6970
fileContents, _ := deployment.GetFile(file.Meta.Name, file.Meta.Hash)
@@ -74,7 +75,7 @@ func TestUpdateConfig(t *testing.T) {
7475
// ensure that the error is cleared after the next config is applied
7576
deployment.SetPodErrorStatus("pod1", nil)
7677
file.Meta.Hash = "5678"
77-
updater.UpdateConfig(deployment, []File{file})
78+
updater.UpdateConfig(deployment, []File{file}, []v1.VolumeMount{})
7879
g.Expect(deployment.GetLatestConfigError()).ToNot(HaveOccurred())
7980
} else {
8081
g.Expect(deployment.GetLatestConfigError()).ToNot(HaveOccurred())
@@ -105,10 +106,10 @@ func TestUpdateConfig_NoChange(t *testing.T) {
105106
}
106107

107108
// Set the initial files on the deployment
108-
deployment.SetFiles([]File{file})
109+
deployment.SetFiles([]File{file}, []v1.VolumeMount{})
109110

110111
// Call UpdateConfig with the same files
111-
updater.UpdateConfig(deployment, []File{file})
112+
updater.UpdateConfig(deployment, []File{file}, []v1.VolumeMount{})
112113

113114
// Verify that no new configuration was sent
114115
g.Expect(fakeBroadcaster.SendCallCount()).To(Equal(0))

internal/controller/nginx/agent/agentfakes/fake_nginx_updater.go

Lines changed: 16 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/controller/nginx/agent/command_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ func TestSubscribe(t *testing.T) {
342342
Contents: []byte("file contents"),
343343
},
344344
}
345-
deployment.SetFiles(files)
345+
deployment.SetFiles(files, []v1.VolumeMount{})
346346
deployment.SetImageVersion("nginx:v1.0.0")
347347

348348
initialAction := &pb.NGINXPlusAction{
@@ -488,7 +488,7 @@ func TestSubscribe_Reset(t *testing.T) {
488488
Contents: []byte("file contents"),
489489
},
490490
}
491-
deployment.SetFiles(files)
491+
deployment.SetFiles(files, []v1.VolumeMount{})
492492
deployment.SetImageVersion("nginx:v1.0.0")
493493

494494
ctx, cancel := createGrpcContextWithCancel()

0 commit comments

Comments
 (0)