Skip to content

Commit 3da168e

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

File tree

12 files changed

+296
-123
lines changed

12 files changed

+296
-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: 48 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,8 @@ type GatewayClass struct {
4035
Conditions []conditions.Condition
4136
// Valid shows whether the GatewayClass is valid.
4237
Valid bool
38+
// ExperimentalSupported indicates whether experimental features are supported.
39+
ExperimentalSupported bool
4340
}
4441

4542
// processedGatewayClasses holds the resources that belong to NGF.
@@ -82,6 +79,7 @@ func buildGatewayClass(
8279
gc *v1.GatewayClass,
8380
nps map[types.NamespacedName]*NginxProxy,
8481
crdVersions map[types.NamespacedName]*metav1.PartialObjectMetadata,
82+
experimentalEnabled bool,
8583
) *GatewayClass {
8684
if gc == nil {
8785
return nil
@@ -92,13 +90,17 @@ func buildGatewayClass(
9290
np = getNginxProxyForGatewayClass(*gc.Spec.ParametersRef, nps)
9391
}
9492

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

9798
return &GatewayClass{
98-
Source: gc,
99-
NginxProxy: np,
100-
Valid: valid,
101-
Conditions: conds,
99+
Source: gc,
100+
NginxProxy: np,
101+
Valid: valid,
102+
Conditions: conds,
103+
ExperimentalSupported: experimental,
102104
}
103105
}
104106

@@ -144,14 +146,14 @@ func validateGatewayClass(
144146
gc *v1.GatewayClass,
145147
npCfg *NginxProxy,
146148
crdVersions map[types.NamespacedName]*metav1.PartialObjectMetadata,
147-
) ([]conditions.Condition, bool) {
149+
) ([]conditions.Condition, bool, bool) {
148150
var conds []conditions.Condition
149151

150-
supportedVersionConds, versionsValid := validateCRDVersions(crdVersions)
152+
supportedVersionConds, versionsValid, experimental := validateCRDVersions(crdVersions)
151153
conds = append(conds, supportedVersionConds...)
152154

153155
if gc.Spec.ParametersRef == nil {
154-
return conds, versionsValid
156+
return conds, versionsValid, experimental
155157
}
156158

157159
path := field.NewPath("spec").Child("parametersRef")
@@ -160,7 +162,7 @@ func validateGatewayClass(
160162
// return early since parametersRef isn't valid
161163
if len(refConds) > 0 {
162164
conds = append(conds, refConds...)
163-
return conds, versionsValid
165+
return conds, versionsValid, experimental
164166
}
165167

166168
if npCfg == nil {
@@ -171,7 +173,7 @@ func validateGatewayClass(
171173
field.NotFound(path.Child("name"), gc.Spec.ParametersRef.Name).Error(),
172174
),
173175
)
174-
return conds, versionsValid
176+
return conds, versionsValid, experimental
175177
}
176178

177179
if !npCfg.Valid {
@@ -181,10 +183,10 @@ func validateGatewayClass(
181183
conditions.NewGatewayClassRefInvalid(msg),
182184
conditions.NewGatewayClassInvalidParameters(msg),
183185
)
184-
return conds, versionsValid
186+
return conds, versionsValid, experimental
185187
}
186188

187-
return append(conds, conditions.NewGatewayClassResolvedRefs()), versionsValid
189+
return append(conds, conditions.NewGatewayClassResolvedRefs()), versionsValid, experimental
188190
}
189191

190192
var supportedParamKinds = map[string]struct{}{
@@ -198,9 +200,9 @@ type apiVersion struct {
198200

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

205207
var unsupported, bestEffort bool
206208

@@ -212,15 +214,23 @@ func validateCRDVersions(
212214
}
213215
}
214216

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

219229
if bestEffort {
220-
return conditions.NewGatewayClassSupportedVersionBestEffort(SupportedVersion), true
230+
return conditions.NewGatewayClassSupportedVersionBestEffort(consts.BundleVersion), true, experimental
221231
}
222232

223-
return nil, true
233+
return nil, true, experimental
224234
}
225235

226236
func parseVersionString(version string) apiVersion {
@@ -245,15 +255,25 @@ func parseVersionString(version string) apiVersion {
245255
}
246256
}
247257

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

251264
for nsname, md := range crdMetadata {
252265
if _, ok := gatewayCRDs[nsname.Name]; ok {
253-
bundleVersion := md.Annotations[BundleVersionAnnotation]
266+
bundleVersion := md.Annotations[consts.BundleVersionAnnotation]
254267
versions = append(versions, parseVersionString(bundleVersion))
268+
269+
// Default to standard channel if annotation is missing
270+
ch := md.Annotations[consts.ChannelAnnotation]
271+
if ch == "" {
272+
ch = string(features.FeatureChannelStandard)
273+
}
274+
channels = append(channels, features.FeatureChannel(ch))
255275
}
256276
}
257277

258-
return versions
278+
return versions, channels
259279
}

0 commit comments

Comments
 (0)