Skip to content

Commit 5f0744a

Browse files
authored
Merge branch 'main' into feat/hostPort
2 parents 917b477 + 7d26857 commit 5f0744a

31 files changed

+1145
-55
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ jobs:
171171
fail-build: false
172172

173173
- name: Upload scan result to GitHub Security tab
174-
uses: github/codeql-action/upload-sarif@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0
174+
uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
175175
continue-on-error: true
176176
with:
177177
sarif_file: ${{ steps.scan.outputs.sarif }}

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ jobs:
165165
if: github.ref_type == 'tag'
166166

167167
- name: Install Cosign
168-
uses: sigstore/cosign-installer@fb28c2b6339dcd94da6e4cbcbc5e888961f6f8c3 # v3.9.0
168+
uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3.9.1
169169
if: github.ref_type == 'tag'
170170

171171
- name: Build binary

.github/workflows/scorecards.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,6 @@ jobs:
6060

6161
# Upload the results to GitHub's code scanning dashboard.
6262
- name: "Upload to code-scanning"
63-
uses: github/codeql-action/upload-sarif@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0
63+
uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
6464
with:
6565
sarif_file: results.sarif

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ repos:
3232
- id: gitleaks
3333

3434
- repo: https://github.com/rbubley/mirrors-prettier
35-
rev: v3.5.3
35+
rev: v3.6.2
3636
hooks:
3737
- id: prettier
3838
types:

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ The following table lists the software versions NGINX Gateway Fabric supports.
6868

6969
| NGINX Gateway Fabric | Gateway API | Kubernetes | NGINX OSS | NGINX Plus | NGINX Agent |
7070
|----------------------|-------------|------------|-----------|------------|-------------|
71-
| Edge | 1.3.0 | 1.25+ | 1.28.0 | R34 | v3.0.2 |
71+
| Edge | 1.3.0 | 1.25+ | 1.28.0 | R34 | v3.0.3 |
7272
| 2.0.1 | 1.3.0 | 1.25+ | 1.28.0 | R34 | v3.0.1 |
7373
| 2.0.0 | 1.3.0 | 1.25+ | 1.28.0 | R34 | v3.0.0 |
7474
| 1.6.2 | 1.2.1 | 1.25+ | 1.27.4 | R33 | --- |

build/Dockerfile.nginx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ ADD --link --chown=101:1001 https://cs.nginx.com/static/keys/nginx_signing.rsa.p
77
FROM nginx:1.28.0-alpine-otel
88

99
# renovate: datasource=github-tags depName=nginx/agent
10-
ARG NGINX_AGENT_VERSION=v3.0.2
10+
ARG NGINX_AGENT_VERSION=v3.0.3
1111
ARG NJS_DIR
1212
ARG NGINX_CONF_DIR
1313
ARG BUILD_AGENT

build/Dockerfile.nginxplus

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ FROM alpine:3.21
88

99
ARG NGINX_PLUS_VERSION=R34
1010
# renovate: datasource=github-tags depName=nginx/agent
11-
ARG NGINX_AGENT_VERSION=v3.0.2
11+
ARG NGINX_AGENT_VERSION=v3.0.3
1212
ARG NJS_DIR
1313
ARG NGINX_CONF_DIR
1414
ARG BUILD_AGENT

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ require (
77
github.com/go-logr/logr v1.4.3
88
github.com/google/go-cmp v0.7.0
99
github.com/google/uuid v1.6.0
10-
github.com/nginx/agent/v3 v3.0.2
10+
github.com/nginx/agent/v3 v3.0.3
1111
github.com/nginx/telemetry-exporter v0.1.4
1212
github.com/onsi/ginkgo/v2 v2.23.4
1313
github.com/onsi/gomega v1.37.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
137137
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
138138
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
139139
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
140-
github.com/nginx/agent/v3 v3.0.2 h1:beO5qFeAVWOiZDkYRyElctbhnjz+g3JDsH2yKZjoRjY=
141-
github.com/nginx/agent/v3 v3.0.2/go.mod h1:O/31aKtii/mpiZmFGMcTNDoLtKzwTyTXOBMSRkMaPvs=
140+
github.com/nginx/agent/v3 v3.0.3 h1:m/CJEVsOZwcMXwtck/AIhWVzhSMLjxi7sLUX6s54zjA=
141+
github.com/nginx/agent/v3 v3.0.3/go.mod h1:r1ANR0lvPk6rabs5WbZTcnLBwkzpEFEPILyC2kLEeig=
142142
github.com/nginx/telemetry-exporter v0.1.4 h1:3ikgKlyz/O57oaBLkxCInMjr74AhGTKr9rHdRAkkl/w=
143143
github.com/nginx/telemetry-exporter v0.1.4/go.mod h1:bl6qmsxgk4a9D0X8R5E3sUNXN2iECPEK1JNbRLhN5C4=
144144
github.com/nginxinc/nginx-plus-go-client/v2 v2.0.1 h1:5VVK38bnELMDWnwfF6dSv57ResXh9AUzeDa72ENj94o=

internal/controller/manager.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ func registerControllers(
440440
objectType: &apiv1.Service{},
441441
name: "user-service", // unique controller names are needed and we have multiple Service ctlrs
442442
options: []controller.Option{
443-
controller.WithK8sPredicate(predicate.ServicePortsChangedPredicate{}),
443+
controller.WithK8sPredicate(predicate.ServiceChangedPredicate{}),
444444
},
445445
},
446446
{

internal/controller/nginx/modules/package-lock.json

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

internal/controller/nginx/modules/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
},
1212
"devDependencies": {
1313
"@vitest/coverage-v8": "^3.2.4",
14-
"prettier": "3.6.0",
14+
"prettier": "3.6.2",
1515
"vitest": "^3.2.4"
1616
},
1717
"type": "module"

internal/controller/state/conditions/conditions.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,18 @@ const (
107107
// has an overlapping hostname:port/path combination with another Route.
108108
PolicyReasonTargetConflict v1alpha2.PolicyConditionReason = "TargetConflict"
109109

110+
// ClientSettingsPolicyAffected is used with the "PolicyAffected" condition when a
111+
// ClientSettingsPolicy is applied to a Gateway, HTTPRoute, or GRPCRoute.
112+
ClientSettingsPolicyAffected v1alpha2.PolicyConditionType = "ClientSettingsPolicyAffected"
113+
114+
// ObservabilityPolicyAffected is used with the "PolicyAffected" condition when an
115+
// ObservabilityPolicy is applied to a HTTPRoute, or GRPCRoute.
116+
ObservabilityPolicyAffected v1alpha2.PolicyConditionType = "ObservabilityPolicyAffected"
117+
118+
// PolicyAffectedReason is used with the "PolicyAffected" condition when a
119+
// ObservabilityPolicy or ClientSettingsPolicy is applied to Gateways or Routes.
120+
PolicyAffectedReason v1alpha2.PolicyConditionReason = "PolicyAffected"
121+
110122
// GatewayResolvedRefs condition indicates whether the controller was able to resolve the
111123
// parametersRef on the Gateway.
112124
GatewayResolvedRefs v1.GatewayConditionType = "ResolvedRefs"
@@ -185,6 +197,19 @@ func ConvertConditions(
185197
return apiConds
186198
}
187199

200+
// HasMatchingCondition checks if the given condition matches any of the existing conditions.
201+
func HasMatchingCondition(existingConditions []Condition, cond Condition) bool {
202+
for _, existing := range existingConditions {
203+
if existing.Type == cond.Type &&
204+
existing.Status == cond.Status &&
205+
existing.Reason == cond.Reason &&
206+
existing.Message == cond.Message {
207+
return true
208+
}
209+
}
210+
return false
211+
}
212+
188213
// NewDefaultGatewayClassConditions returns Conditions that indicate that the GatewayClass is accepted and that the
189214
// Gateway API CRD versions are supported.
190215
func NewDefaultGatewayClassConditions() []Condition {
@@ -398,6 +423,17 @@ func NewRouteBackendRefUnsupportedValue(msg string) Condition {
398423
}
399424
}
400425

426+
// NewRouteBackendRefUnsupportedProtocol returns a Condition that indicates that the Route has a backendRef with
427+
// an unsupported protocol.
428+
func NewRouteBackendRefUnsupportedProtocol(msg string) Condition {
429+
return Condition{
430+
Type: string(v1.RouteConditionResolvedRefs),
431+
Status: metav1.ConditionFalse,
432+
Reason: string(v1.RouteReasonUnsupportedProtocol),
433+
Message: msg,
434+
}
435+
}
436+
401437
// NewRouteInvalidGateway returns a Condition that indicates that the Route is not Accepted because the Gateway it
402438
// references is invalid.
403439
func NewRouteInvalidGateway() Condition {
@@ -940,3 +976,25 @@ func NewSnippetsFilterAccepted() Condition {
940976
Message: "SnippetsFilter is accepted",
941977
}
942978
}
979+
980+
// NewObservabilityPolicyAffected returns a Condition that indicates that an ObservabilityPolicy
981+
// is applied to the resource.
982+
func NewObservabilityPolicyAffected() Condition {
983+
return Condition{
984+
Type: string(ObservabilityPolicyAffected),
985+
Status: metav1.ConditionTrue,
986+
Reason: string(PolicyAffectedReason),
987+
Message: "ObservabilityPolicy is applied to the resource",
988+
}
989+
}
990+
991+
// NewClientSettingsPolicyAffected returns a Condition that indicates that a ClientSettingsPolicy
992+
// is applied to the resource.
993+
func NewClientSettingsPolicyAffected() Condition {
994+
return Condition{
995+
Type: string(ClientSettingsPolicyAffected),
996+
Status: metav1.ConditionTrue,
997+
Reason: string(PolicyAffectedReason),
998+
Message: "ClientSettingsPolicy is applied to the resource",
999+
}
1000+
}

internal/controller/state/conditions/conditions_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,43 @@ func TestConvertConditions(t *testing.T) {
105105
result := ConvertConditions(conds, generation, time)
106106
g.Expect(result).Should(Equal(expected))
107107
}
108+
109+
func TestHasMatchingCondition(t *testing.T) {
110+
t.Parallel()
111+
112+
tests := []struct {
113+
condition Condition
114+
name string
115+
conds []Condition
116+
expected bool
117+
}{
118+
{
119+
name: "no conditions in the list",
120+
conds: nil,
121+
condition: NewClientSettingsPolicyAffected(),
122+
expected: false,
123+
},
124+
{
125+
name: "condition matches existing condition",
126+
conds: []Condition{NewClientSettingsPolicyAffected()},
127+
condition: NewClientSettingsPolicyAffected(),
128+
expected: true,
129+
},
130+
{
131+
name: "condition does not match existing condition",
132+
conds: []Condition{NewClientSettingsPolicyAffected()},
133+
condition: NewObservabilityPolicyAffected(),
134+
expected: false,
135+
},
136+
}
137+
138+
for _, test := range tests {
139+
t.Run(test.name, func(t *testing.T) {
140+
t.Parallel()
141+
g := NewWithT(t)
142+
143+
result := HasMatchingCondition(test.conds, test.condition)
144+
g.Expect(result).To(Equal(test.expected))
145+
})
146+
}
147+
}

internal/controller/state/graph/backend_refs.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ import (
1717
"github.com/nginx/nginx-gateway-fabric/internal/framework/helpers"
1818
)
1919

20+
const (
21+
AppProtocolTypeH2C string = "kubernetes.io/h2c"
22+
AppProtocolTypeWS string = "kubernetes.io/ws"
23+
AppProtocolTypeWSS string = "kubernetes.io/wss"
24+
)
25+
2026
// BackendRef is an internal representation of a backendRef in an HTTP/GRPC/TLSRoute.
2127
type BackendRef struct {
2228
// BackendTLSPolicy is the BackendTLSPolicy of the Service which is referenced by the backendRef.
@@ -200,6 +206,23 @@ func createBackendRef(
200206
return backendRef, append(conds, conditions.NewRouteBackendRefUnsupportedValue(err.Error()))
201207
}
202208

209+
if svcPort.AppProtocol != nil {
210+
err = validateRouteBackendRefAppProtocol(route.RouteType, *svcPort.AppProtocol, backendTLSPolicy)
211+
if err != nil {
212+
backendRef := BackendRef{
213+
SvcNsName: svcNsName,
214+
BackendTLSPolicy: backendTLSPolicy,
215+
ServicePort: svcPort,
216+
Weight: weight,
217+
Valid: false,
218+
IsMirrorBackend: ref.MirrorBackendIdx != nil,
219+
InvalidForGateways: invalidForGateways,
220+
}
221+
222+
return backendRef, append(conds, conditions.NewRouteBackendRefUnsupportedProtocol(err.Error()))
223+
}
224+
}
225+
203226
backendRef := BackendRef{
204227
SvcNsName: svcNsName,
205228
BackendTLSPolicy: backendTLSPolicy,
@@ -414,6 +437,56 @@ func validateBackendRef(
414437
return true, conditions.Condition{}
415438
}
416439

440+
// validateRouteBackendRefAppProtocol checks if a given RouteType supports sending traffic to a service AppProtocol.
441+
// Returns nil if true or AppProtocol is not a Kubernetes Standard Application Protocol.
442+
func validateRouteBackendRefAppProtocol(
443+
routeType RouteType,
444+
appProtocol string,
445+
backendTLSPolicy *BackendTLSPolicy,
446+
) error {
447+
err := fmt.Errorf(
448+
"route type %s does not support service port appProtocol %s",
449+
routeType,
450+
appProtocol,
451+
)
452+
453+
// Currently we only support recognition of the Kubernetes Standard Application Protocols defined in KEP-3726.
454+
switch appProtocol {
455+
case AppProtocolTypeH2C:
456+
if routeType == RouteTypeGRPC {
457+
return nil
458+
}
459+
460+
if routeType == RouteTypeHTTP {
461+
return fmt.Errorf("%w; nginx does not support proxying to upstreams with http2 or h2c", err)
462+
}
463+
464+
return err
465+
case AppProtocolTypeWS:
466+
if routeType == RouteTypeHTTP {
467+
return nil
468+
}
469+
470+
return err
471+
case AppProtocolTypeWSS:
472+
if routeType == RouteTypeHTTP {
473+
if backendTLSPolicy != nil {
474+
return nil
475+
}
476+
477+
return fmt.Errorf("%w; missing corresponding BackendTLSPolicy", err)
478+
}
479+
480+
if routeType == RouteTypeTLS {
481+
return nil
482+
}
483+
484+
return err
485+
}
486+
487+
return nil
488+
}
489+
417490
func validateWeight(weight int32) error {
418491
const (
419492
minWeight = 0

0 commit comments

Comments
 (0)