Skip to content

Commit 6e0570b

Browse files
committed
add tls.backend field to specify gateway cert
1 parent b52a208 commit 6e0570b

File tree

14 files changed

+1419
-848
lines changed

14 files changed

+1419
-848
lines changed

internal/controller/manager.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,10 @@ func StartManager(cfg config.Config) error {
139139
GenericValidator: genericValidator,
140140
PolicyValidator: policyManager,
141141
},
142-
EventRecorder: recorder,
143-
MustExtractGVK: mustExtractGVK,
144-
PlusSecrets: plusSecrets,
142+
EventRecorder: recorder,
143+
MustExtractGVK: mustExtractGVK,
144+
PlusSecrets: plusSecrets,
145+
ExperimentalFeatures: cfg.ExperimentalFeatures,
145146
})
146147

147148
var handlerCollector handlerMetricsCollector = collectors.NewControllerNoopCollector()

internal/controller/nginx/config/base_http_config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ var baseHTTPTemplate = gotemplate.Must(gotemplate.New("baseHttp").Parse(baseHTTP
1212

1313
type httpConfig struct {
1414
DNSResolver *dataplane.DNSResolverConfig
15+
GatewaySecretID dataplane.SSLKeyPairID
1516
Includes []shared.Include
1617
NginxReadinessProbePort int32
1718
IPFamily shared.IPFamily
@@ -27,6 +28,7 @@ func executeBaseHTTPConfig(conf dataplane.Configuration) []executeResult {
2728
NginxReadinessProbePort: conf.BaseHTTPConfig.NginxReadinessProbePort,
2829
IPFamily: getIPFamily(conf.BaseHTTPConfig),
2930
DNSResolver: conf.BaseHTTPConfig.DNSResolver,
31+
GatewaySecretID: conf.GatewaySecretID,
3032
}
3133

3234
results := make([]executeResult, 0, len(includes)+1)

internal/controller/nginx/config/base_http_config_template.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ server {
4848
}
4949
}
5050
51+
{{- if $.GatewaySecretID }}
52+
# Gateway Certificate
53+
proxy_ssl_certificate /etc/nginx/secrets/{{ $.GatewaySecretID }}.pem;
54+
proxy_ssl_certificate_key /etc/nginx/secrets/{{ $.GatewaySecretID }}.pem;
55+
{{- end }}
56+
5157
{{ range $i := .Includes -}}
5258
include {{ $i.Name }};
5359
{{ end -}}

internal/controller/nginx/config/base_http_config_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,3 +284,45 @@ func TestExecuteBaseHttp_DNSResolver(t *testing.T) {
284284
})
285285
}
286286
}
287+
288+
func TestExecuteBaseHttp_GatewaySecretID(t *testing.T) {
289+
t.Parallel()
290+
291+
tests := []struct {
292+
name string
293+
expectedConfig string
294+
conf dataplane.Configuration
295+
}{
296+
{
297+
name: "with GatewaySecretID",
298+
conf: dataplane.Configuration{
299+
GatewaySecretID: "client-secret",
300+
},
301+
expectedConfig: "proxy_ssl_certificate /etc/nginx/secrets/client-secret.pem;" +
302+
"\nproxy_ssl_certificate_key /etc/nginx/secrets/client-secret.pem;",
303+
},
304+
{
305+
name: "without GatewaySecretID",
306+
conf: dataplane.Configuration{
307+
GatewaySecretID: "",
308+
},
309+
expectedConfig: "",
310+
},
311+
}
312+
313+
for _, test := range tests {
314+
t.Run(test.name, func(t *testing.T) {
315+
t.Parallel()
316+
g := NewWithT(t)
317+
318+
res := executeBaseHTTPConfig(test.conf)
319+
g.Expect(res).To(HaveLen(1))
320+
321+
httpConfig := string(res[0].data)
322+
323+
if test.expectedConfig != "" {
324+
g.Expect(httpConfig).To(ContainSubstring(test.expectedConfig))
325+
}
326+
})
327+
}
328+
}

internal/controller/state/change_processor.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ type ChangeProcessorConfig struct {
6363
GatewayCtlrName string
6464
// GatewayClassName is the name of the GatewayClass resource.
6565
GatewayClassName string
66+
// ExperimentalFeatures indicates whether experimental features are enabled.
67+
ExperimentalFeatures bool
6668
}
6769

6870
// ChangeProcessorImpl is an implementation of ChangeProcessor.
@@ -269,6 +271,7 @@ func (c *ChangeProcessorImpl) Process() *graph.Graph {
269271
c.cfg.PlusSecrets,
270272
c.cfg.Validators,
271273
c.cfg.Logger,
274+
c.cfg.ExperimentalFeatures,
272275
)
273276

274277
return c.latestGraph

internal/controller/state/conditions/conditions.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,14 @@ const (
139139
// parametersRef resource is invalid.
140140
GatewayReasonParamsRefInvalid v1.GatewayConditionReason = "ParametersRefInvalid"
141141

142+
// GatewayReasonSecretRefInvalid is used with the "GatewayResolvedRefs" condition when the
143+
// secretRef resource is invalid.
144+
GatewayReasonSecretRefInvalid v1.GatewayConditionReason = "SecretRefInvalid"
145+
146+
// GatewayReasonSecretRefNotPermitted is used with the "GatewayResolvedRefs" condition when the
147+
// secretRef resource is not permitted by any ReferenceGrant.
148+
GatewayReasonSecretRefNotPermitted v1.GatewayConditionReason = "SecretRefNotPermitted"
149+
142150
// PolicyReasonAncestorLimitReached is used with the "PolicyAccepted" condition when a policy
143151
// cannot be applied because the ancestor status list has reached the maximum size of 16.
144152
PolicyReasonAncestorLimitReached v1alpha2.PolicyConditionReason = "AncestorLimitReached"
@@ -297,6 +305,27 @@ func NewGatewayClassUnsupportedVersion(recommendedVersion string) []Condition {
297305
}
298306
}
299307

308+
// NewGatewaySecretRefNotPermitted returns Condition that indicates that the Gateway references a TLS secret that is not
309+
// permitted by any ReferenceGrant.
310+
func NewGatewaySecretRefNotPermitted(msg string) Condition {
311+
return Condition{
312+
Type: string(GatewayReasonResolvedRefs),
313+
Status: metav1.ConditionFalse,
314+
Reason: string(GatewayReasonSecretRefNotPermitted),
315+
Message: msg,
316+
}
317+
}
318+
319+
// NewGatewaySecretRefInvalid returns Condition that indicates that the Gateway references a TLS secret that is invalid.
320+
func NewGatewaySecretRefInvalid(msg string) Condition {
321+
return Condition{
322+
Type: string(GatewayReasonResolvedRefs),
323+
Status: metav1.ConditionFalse,
324+
Reason: string(GatewayReasonSecretRefInvalid),
325+
Message: msg,
326+
}
327+
}
328+
300329
// NewGatewayClassConflict returns a Condition that indicates that the GatewayClass is not accepted
301330
// due to a conflict with another GatewayClass.
302331
func NewGatewayClassConflict() Condition {

internal/controller/state/dataplane/configuration.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ func BuildConfiguration(
7070
nginxPlus = buildNginxPlus(gateway)
7171
}
7272

73+
var gatewaySecretRef SSLKeyPairID
74+
if gateway.Valid && gateway.SecretRef != nil {
75+
gatewaySecretRef = generateSSLKeyPairID(*gateway.SecretRef)
76+
}
77+
7378
config := Configuration{
7479
HTTPServers: httpServers,
7580
SSLServers: sslServers,
@@ -81,9 +86,10 @@ func BuildConfiguration(
8186
gateway,
8287
serviceResolver,
8388
g.ReferencedServices,
84-
baseHTTPConfig.IPFamily),
89+
baseHTTPConfig.IPFamily,
90+
),
8591
BackendGroups: backendGroups,
86-
SSLKeyPairs: buildSSLKeyPairs(g.ReferencedSecrets, gateway.Listeners),
92+
SSLKeyPairs: buildSSLKeyPairs(g.ReferencedSecrets, gateway),
8793
CertBundles: buildCertBundles(
8894
buildRefCertificateBundles(g.ReferencedSecrets, g.ReferencedCaCertConfigMaps),
8995
backendGroups,
@@ -96,6 +102,7 @@ func BuildConfiguration(
96102
MainSnippets: buildSnippetsForContext(gatewaySnippetsFilters, ngfAPIv1alpha1.NginxContextMain),
97103
AuxiliarySecrets: buildAuxiliarySecrets(g.PlusSecrets),
98104
WorkerConnections: buildWorkerConnections(gateway),
105+
GatewaySecretID: gatewaySecretRef,
99106
}
100107

101108
return config
@@ -248,14 +255,14 @@ func buildStreamUpstreams(
248255
}
249256

250257
// buildSSLKeyPairs builds the SSLKeyPairs from the Secrets. It will only include Secrets that are referenced by
251-
// valid listeners, so that we don't include unused Secrets in the configuration of the data plane.
258+
// valid gateway and its listeners, so that we don't include unused Secrets in the configuration of the data plane.
252259
func buildSSLKeyPairs(
253260
secrets map[types.NamespacedName]*graph.Secret,
254-
listeners []*graph.Listener,
261+
gateway *graph.Gateway,
255262
) map[SSLKeyPairID]SSLKeyPair {
256263
keyPairs := make(map[SSLKeyPairID]SSLKeyPair)
257264

258-
for _, l := range listeners {
265+
for _, l := range gateway.Listeners {
259266
if l.Valid && l.ResolvedSecret != nil {
260267
id := generateSSLKeyPairID(*l.ResolvedSecret)
261268
secret := secrets[*l.ResolvedSecret]
@@ -268,6 +275,15 @@ func buildSSLKeyPairs(
268275
}
269276
}
270277

278+
if gateway.Valid && gateway.SecretRef != nil {
279+
id := generateSSLKeyPairID(*gateway.SecretRef)
280+
secret := secrets[*gateway.SecretRef]
281+
keyPairs[id] = SSLKeyPair{
282+
Cert: secret.CertBundle.Cert.TLSCert,
283+
Key: secret.CertBundle.Cert.TLSPrivateKey,
284+
}
285+
}
286+
271287
return keyPairs
272288
}
273289

@@ -1042,8 +1058,6 @@ func buildBaseHTTPConfig(
10421058
}
10431059
}
10441060

1045-
baseConfig.RewriteClientIPSettings = buildRewriteClientIPConfig(np.RewriteClientIP)
1046-
10471061
if np.Kubernetes != nil {
10481062
var containerSpec *ngfAPIv1alpha2.ContainerSpec
10491063
if np.Kubernetes.Deployment != nil {
@@ -1056,6 +1070,8 @@ func buildBaseHTTPConfig(
10561070
}
10571071
}
10581072

1073+
baseConfig.RewriteClientIPSettings = buildRewriteClientIPConfig(np.RewriteClientIP)
1074+
10591075
baseConfig.DNSResolver = buildDNSResolverConfig(np.DNSResolver)
10601076

10611077
return baseConfig

0 commit comments

Comments
 (0)