Skip to content

Commit bc86ffd

Browse files
committed
Use constants for annotations and features
1 parent f32648d commit bc86ffd

File tree

12 files changed

+298
-123
lines changed

12 files changed

+298
-123
lines changed

internal/controller/manager.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
3737
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
3838
gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
39+
"sigs.k8s.io/gateway-api/pkg/consts"
3940

4041
ngfAPIv1alpha1 "github.com/nginx/nginx-gateway-fabric/v2/apis/v1alpha1"
4142
ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/v2/apis/v1alpha2"
@@ -493,7 +494,7 @@ func registerControllers(
493494
options: []controller.Option{
494495
controller.WithOnlyMetadata(),
495496
controller.WithK8sPredicate(
496-
predicate.AnnotationPredicate{Annotation: graph.BundleVersionAnnotation},
497+
predicate.AnnotationPredicate{Annotation: consts.BundleVersionAnnotation},
497498
),
498499
},
499500
},

internal/controller/state/change_processor.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
v1 "sigs.k8s.io/gateway-api/apis/v1"
1616
"sigs.k8s.io/gateway-api/apis/v1alpha2"
1717
"sigs.k8s.io/gateway-api/apis/v1beta1"
18+
"sigs.k8s.io/gateway-api/pkg/consts"
1819

1920
ngfAPIv1alpha1 "github.com/nginx/nginx-gateway-fabric/v2/apis/v1alpha1"
2021
ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/v2/apis/v1alpha2"
@@ -63,6 +64,8 @@ type ChangeProcessorConfig struct {
6364
GatewayCtlrName string
6465
// GatewayClassName is the name of the GatewayClass resource.
6566
GatewayClassName string
67+
// ExperimentalFeatures indicates if experimental features are enabled.
68+
ExperimentalFeatures bool
6669
}
6770

6871
// ChangeProcessorImpl is an implementation of ChangeProcessor.
@@ -190,7 +193,7 @@ func NewChangeProcessorImpl(cfg ChangeProcessorConfig) *ChangeProcessorImpl {
190193
{
191194
gvk: cfg.MustExtractGVK(&apiext.CustomResourceDefinition{}),
192195
store: newObjectStoreMapAdapter(clusterStore.CRDMetadata),
193-
predicate: annotationChangedPredicate{annotation: graph.BundleVersionAnnotation},
196+
predicate: annotationChangedPredicate{annotation: consts.BundleVersionAnnotation},
194197
},
195198
{
196199
gvk: cfg.MustExtractGVK(&ngfAPIv1alpha2.NginxProxy{}),
@@ -275,6 +278,7 @@ func (c *ChangeProcessorImpl) Process() *graph.Graph {
275278
c.cfg.PlusSecrets,
276279
c.cfg.Validators,
277280
c.cfg.Logger,
281+
c.cfg.ExperimentalFeatures,
278282
)
279283

280284
return c.latestGraph

internal/controller/state/change_processor_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
v1 "sigs.k8s.io/gateway-api/apis/v1"
1919
"sigs.k8s.io/gateway-api/apis/v1alpha2"
2020
"sigs.k8s.io/gateway-api/apis/v1beta1"
21+
"sigs.k8s.io/gateway-api/pkg/consts"
2122

2223
ngfAPIv1alpha1 "github.com/nginx/nginx-gateway-fabric/v2/apis/v1alpha1"
2324
ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/v2/apis/v1alpha2"
@@ -666,13 +667,13 @@ var _ = Describe("ChangeProcessor", func() {
666667
ObjectMeta: metav1.ObjectMeta{
667668
Name: "gatewayclasses.gateway.networking.k8s.io",
668669
Annotations: map[string]string{
669-
graph.BundleVersionAnnotation: graph.SupportedVersion,
670+
consts.BundleVersionAnnotation: consts.BundleVersion,
670671
},
671672
},
672673
}
673674

674675
gatewayAPICRDUpdated = gatewayAPICRD.DeepCopy()
675-
gatewayAPICRDUpdated.Annotations[graph.BundleVersionAnnotation] = "v1.99.0"
676+
gatewayAPICRDUpdated.Annotations[consts.BundleVersionAnnotation] = "v1.99.0"
676677
})
677678
BeforeEach(func() {
678679
expRouteHR1 = &graph.L7Route{
@@ -1556,7 +1557,7 @@ var _ = Describe("ChangeProcessor", func() {
15561557
}
15571558

15581559
expGraph.GatewayClass.Conditions = conditions.NewGatewayClassSupportedVersionBestEffort(
1559-
graph.SupportedVersion,
1560+
consts.BundleVersion,
15601561
)
15611562

15621563
processAndValidateGraph(expGraph)
@@ -1574,7 +1575,7 @@ var _ = Describe("ChangeProcessor", func() {
15741575
}
15751576

15761577
expGraph.GatewayClass.Conditions = conditions.NewGatewayClassSupportedVersionBestEffort(
1577-
graph.SupportedVersion,
1578+
consts.BundleVersion,
15781579
)
15791580

15801581
graphCfg := processor.Process()

internal/controller/state/graph/gatewayclass.go

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,13 @@ import (
88
"k8s.io/apimachinery/pkg/util/validation/field"
99
"sigs.k8s.io/controller-runtime/pkg/client"
1010
v1 "sigs.k8s.io/gateway-api/apis/v1"
11+
"sigs.k8s.io/gateway-api/pkg/consts"
12+
"sigs.k8s.io/gateway-api/pkg/features"
1113

1214
"github.com/nginx/nginx-gateway-fabric/v2/internal/controller/state/conditions"
1315
"github.com/nginx/nginx-gateway-fabric/v2/internal/framework/kinds"
1416
)
1517

16-
const (
17-
// BundleVersionAnnotation is the annotation on Gateway API CRDs that contains the installed version.
18-
BundleVersionAnnotation = "gateway.networking.k8s.io/bundle-version"
19-
// SupportedVersion is the supported version of the Gateway API CRDs.
20-
SupportedVersion = "v1.4.0"
21-
)
22-
2318
var gatewayCRDs = map[string]apiVersion{
2419
"gatewayclasses.gateway.networking.k8s.io": {},
2520
"gateways.gateway.networking.k8s.io": {},
@@ -40,6 +35,10 @@ type GatewayClass struct {
4035
Conditions []conditions.Condition
4136
// Valid shows whether the GatewayClass is valid.
4237
Valid bool
38+
// Experimental indicates whether experimental features are supported.
39+
// This is true only when BOTH the ExperimentalFeatures config flag is enabled
40+
// AND the Gateway API CRDs have the experimental channel annotation.
41+
Experimental bool
4342
}
4443

4544
// processedGatewayClasses holds the resources that belong to NGF.
@@ -82,6 +81,7 @@ func buildGatewayClass(
8281
gc *v1.GatewayClass,
8382
nps map[types.NamespacedName]*NginxProxy,
8483
crdVersions map[types.NamespacedName]*metav1.PartialObjectMetadata,
84+
experimentalEnabled bool,
8585
) *GatewayClass {
8686
if gc == nil {
8787
return nil
@@ -92,13 +92,17 @@ func buildGatewayClass(
9292
np = getNginxProxyForGatewayClass(*gc.Spec.ParametersRef, nps)
9393
}
9494

95-
conds, valid := validateGatewayClass(gc, np, crdVersions)
95+
conds, valid, crdExperimental := validateGatewayClass(gc, np, crdVersions)
96+
97+
// Experimental features are enabled only if both the config flag AND CRD channel are experimental
98+
experimental := experimentalEnabled && crdExperimental
9699

97100
return &GatewayClass{
98-
Source: gc,
99-
NginxProxy: np,
100-
Valid: valid,
101-
Conditions: conds,
101+
Source: gc,
102+
NginxProxy: np,
103+
Valid: valid,
104+
Conditions: conds,
105+
Experimental: experimental,
102106
}
103107
}
104108

@@ -144,14 +148,14 @@ func validateGatewayClass(
144148
gc *v1.GatewayClass,
145149
npCfg *NginxProxy,
146150
crdVersions map[types.NamespacedName]*metav1.PartialObjectMetadata,
147-
) ([]conditions.Condition, bool) {
151+
) ([]conditions.Condition, bool, bool) {
148152
var conds []conditions.Condition
149153

150-
supportedVersionConds, versionsValid := validateCRDVersions(crdVersions)
154+
supportedVersionConds, versionsValid, experimental := validateCRDVersions(crdVersions)
151155
conds = append(conds, supportedVersionConds...)
152156

153157
if gc.Spec.ParametersRef == nil {
154-
return conds, versionsValid
158+
return conds, versionsValid, experimental
155159
}
156160

157161
path := field.NewPath("spec").Child("parametersRef")
@@ -160,7 +164,7 @@ func validateGatewayClass(
160164
// return early since parametersRef isn't valid
161165
if len(refConds) > 0 {
162166
conds = append(conds, refConds...)
163-
return conds, versionsValid
167+
return conds, versionsValid, experimental
164168
}
165169

166170
if npCfg == nil {
@@ -171,7 +175,7 @@ func validateGatewayClass(
171175
field.NotFound(path.Child("name"), gc.Spec.ParametersRef.Name).Error(),
172176
),
173177
)
174-
return conds, versionsValid
178+
return conds, versionsValid, experimental
175179
}
176180

177181
if !npCfg.Valid {
@@ -181,10 +185,10 @@ func validateGatewayClass(
181185
conditions.NewGatewayClassRefInvalid(msg),
182186
conditions.NewGatewayClassInvalidParameters(msg),
183187
)
184-
return conds, versionsValid
188+
return conds, versionsValid, experimental
185189
}
186190

187-
return append(conds, conditions.NewGatewayClassResolvedRefs()), versionsValid
191+
return append(conds, conditions.NewGatewayClassResolvedRefs()), versionsValid, experimental
188192
}
189193

190194
var supportedParamKinds = map[string]struct{}{
@@ -198,9 +202,9 @@ type apiVersion struct {
198202

199203
func validateCRDVersions(
200204
crdMetadata map[types.NamespacedName]*metav1.PartialObjectMetadata,
201-
) (conds []conditions.Condition, valid bool) {
202-
installedAPIVersions := getBundleVersions(crdMetadata)
203-
supportedAPIVersion := parseVersionString(SupportedVersion)
205+
) (conds []conditions.Condition, valid bool, experimental bool) {
206+
installedAPIVersions, channels := getBundleVersions(crdMetadata)
207+
supportedAPIVersion := parseVersionString(consts.BundleVersion)
204208

205209
var unsupported, bestEffort bool
206210

@@ -212,15 +216,23 @@ func validateCRDVersions(
212216
}
213217
}
214218

219+
// Check if any CRD is using experimental channel
220+
for _, ch := range channels {
221+
if ch == features.FeatureChannelExperimental {
222+
experimental = true
223+
break
224+
}
225+
}
226+
215227
if unsupported {
216-
return conditions.NewGatewayClassUnsupportedVersion(SupportedVersion), false
228+
return conditions.NewGatewayClassUnsupportedVersion(consts.BundleVersion), false, experimental
217229
}
218230

219231
if bestEffort {
220-
return conditions.NewGatewayClassSupportedVersionBestEffort(SupportedVersion), true
232+
return conditions.NewGatewayClassSupportedVersionBestEffort(consts.BundleVersion), true, experimental
221233
}
222234

223-
return nil, true
235+
return nil, true, experimental
224236
}
225237

226238
func parseVersionString(version string) apiVersion {
@@ -245,15 +257,25 @@ func parseVersionString(version string) apiVersion {
245257
}
246258
}
247259

248-
func getBundleVersions(crdMetadata map[types.NamespacedName]*metav1.PartialObjectMetadata) []apiVersion {
260+
func getBundleVersions(
261+
crdMetadata map[types.NamespacedName]*metav1.PartialObjectMetadata,
262+
) ([]apiVersion, []features.FeatureChannel) {
249263
versions := make([]apiVersion, 0, len(gatewayCRDs))
264+
channels := make([]features.FeatureChannel, 0, len(gatewayCRDs))
250265

251266
for nsname, md := range crdMetadata {
252267
if _, ok := gatewayCRDs[nsname.Name]; ok {
253-
bundleVersion := md.Annotations[BundleVersionAnnotation]
268+
bundleVersion := md.Annotations[consts.BundleVersionAnnotation]
254269
versions = append(versions, parseVersionString(bundleVersion))
270+
271+
// Default to standard channel if annotation is missing
272+
ch := md.Annotations[consts.ChannelAnnotation]
273+
if ch == "" {
274+
ch = string(features.FeatureChannelStandard)
275+
}
276+
channels = append(channels, features.FeatureChannel(ch))
255277
}
256278
}
257279

258-
return versions
280+
return versions, channels
259281
}

0 commit comments

Comments
 (0)