Skip to content

Commit 06846a4

Browse files
authored
Merge pull request crossplane#6241 from jbw976/ssa-to-beta
Promote Claim Server Side Apply to Beta
2 parents c766208 + beff734 commit 06846a4

File tree

8 files changed

+46
-84
lines changed

8 files changed

+46
-84
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,6 @@ jobs:
223223
matrix:
224224
test-suite:
225225
- base
226-
- ssa-claims
227226
- realtime-compositions
228227
- package-dependency-updates
229228
- package-signature-verification
@@ -278,7 +277,7 @@ jobs:
278277
echo "Error: Minor version cannot be decremented below 0"
279278
exit 1
280279
fi
281-
280+
282281
echo "CROSSPLANE_PRIOR_VERSION=$MAJOR.$MINOR" >> $GITHUB_ENV
283282
284283

cmd/crossplane/core/core.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,13 @@ type startCommand struct {
112112

113113
EnableExternalSecretStores bool `group:"Alpha Features:" help:"Enable support for External Secret Stores."`
114114
EnableRealtimeCompositions bool `group:"Alpha Features:" help:"Enable support for realtime compositions, i.e. watching composed resources and reconciling compositions immediately when any of the composed resources is updated."`
115-
EnableSSAClaims bool `group:"Alpha Features:" help:"Enable support for using Kubernetes server-side apply to sync claims with composite resources (XRs)."`
116115
EnableDependencyVersionUpgrades bool `group:"Alpha Features:" help:"Enable support for upgrading dependency versions when the parent package is updated."`
117116
EnableSignatureVerification bool `group:"Alpha Features:" help:"Enable support for package signature verification via ImageConfig API."`
118117

119118
EnableCompositionWebhookSchemaValidation bool `default:"true" group:"Beta Features:" help:"Enable support for Composition validation using schemas."`
120119
EnableDeploymentRuntimeConfigs bool `default:"true" group:"Beta Features:" help:"Enable support for Deployment Runtime Configs."`
121120
EnableUsages bool `default:"true" group:"Beta Features:" help:"Enable support for deletion ordering and resource protection with Usages."`
121+
EnableSSAClaims bool `default:"true" group:"Beta Features:" help:"Enable support for using Kubernetes server-side apply to sync claims with composite resources (XRs)."`
122122

123123
// These are GA features that previously had alpha or beta feature flags.
124124
// You can't turn off a GA feature. We maintain the flags to avoid breaking
@@ -280,8 +280,8 @@ func (c *startCommand) Run(s *runtime.Scheme, log logging.Logger) error { //noli
280280
log.Info("Beta feature enabled", "flag", features.EnableBetaDeploymentRuntimeConfigs)
281281
}
282282
if c.EnableSSAClaims {
283-
o.Features.Enable(features.EnableAlphaClaimSSA)
284-
log.Info("Alpha feature enabled", "flag", features.EnableAlphaClaimSSA)
283+
o.Features.Enable(features.EnableBetaClaimSSA)
284+
log.Info("Beta feature enabled", "flag", features.EnableBetaClaimSSA)
285285
}
286286
if c.EnableDependencyVersionUpgrades {
287287
o.Features.Enable(features.EnableAlphaDependencyVersionUpgrades)

contributing/guide-api-promotion.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ based on the workflow defined above.
8282
* **Note** that the version passed into the migrator is the **"old"**
8383
version you want to migrate **from**, not the target version you want to
8484
migrate to
85+
1. Update the [feature flag] for this API to reflect its new maturity level
86+
1. Update the [feature flag docs] to reflect the new maturity level there as well
8587

8688
<!-- Links -->
8789
[#6148]: https://github.com/crossplane/crossplane/issues/6148
@@ -94,4 +96,6 @@ based on the workflow defined above.
9496
[`generate.go`]: https://github.com/crossplane/crossplane/blob/release-1.18/apis/generate.go
9597
[duplicate script]: https://github.com/crossplane/crossplane/blob/release-1.18/hack/duplicate_api_type.sh
9698
[`cluster/crds`]: https://github.com/crossplane/crossplane/tree/release-1.18/cluster/crds
97-
[migrator]: https://github.com/crossplane/crossplane/blob/release-1.18/cmd/crossplane/core/init.go#L75-L79
99+
[migrator]: https://github.com/crossplane/crossplane/blob/release-1.18/cmd/crossplane/core/init.go#L75-L79
100+
[feature flag]: https://github.com/crossplane/crossplane/blob/release-1.18/cmd/crossplane/core/core.go#L112-L134
101+
[feature flag docs]: https://docs.crossplane.io/latest/software/install/#feature-flags

internal/controller/apiextensions/offered/reconciler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reco
437437
// flag is enabled. Otherwise, we start claim reconcilers with the default
438438
// client-side syncer. If we use a server-side syncer we also need to handle
439439
// upgrading fields that were previously managed using client-side apply.
440-
if r.options.Features.Enabled(features.EnableAlphaClaimSSA) {
440+
if r.options.Features.Enabled(features.EnableBetaClaimSSA) {
441441
o = append(o,
442442
claim.WithCompositeSyncer(claim.NewServerSideCompositeSyncer(r.engine.GetClient(), names.NewNameGenerator(r.engine.GetClient()))),
443443
claim.WithManagedFieldsUpgrader(claim.NewPatchingManagedFieldsUpgrader(r.engine.GetClient())),

internal/features/features.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,6 @@ const (
3131
// when any MR is updated.
3232
EnableAlphaRealtimeCompositions feature.Flag = "EnableAlphaRealtimeCompositions"
3333

34-
// EnableAlphaClaimSSA enables alpha support for using server-side apply in
35-
// the claim controller. See the below issue for more details:
36-
// https://github.com/crossplane/crossplane/issues/4581
37-
EnableAlphaClaimSSA feature.Flag = "EnableAlphaClaimSSA"
38-
3934
// EnableAlphaDependencyVersionUpgrades enables alpha support for upgrading the version of a package's dependencies
4035
// when needed.
4136
EnableAlphaDependencyVersionUpgrades feature.Flag = "EnableAlphaDependencyVersionUpgrades"
@@ -61,4 +56,9 @@ const (
6156
// protection with Usage resource. See the below design for more details.
6257
// https://github.com/crossplane/crossplane/blob/19ea23/design/one-pager-generic-usage-type.md
6358
EnableBetaUsages feature.Flag = "EnableBetaUsages"
59+
60+
// EnableBetaClaimSSA enables beta support for using server-side apply in
61+
// the claim controller. See the below issue for more details:
62+
// https://github.com/crossplane/crossplane/issues/4581
63+
EnableBetaClaimSSA feature.Flag = "EnableBetaClaimSSA"
6464
)

test/e2e/apiextensions_test.go

Lines changed: 14 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,6 @@ import (
3434
"github.com/crossplane/crossplane/test/e2e/funcs"
3535
)
3636

37-
const (
38-
// SuiteSSAClaims is the value for the config.LabelTestSuite label to be
39-
// assigned to tests that should be part of the SSAClaims test suite.
40-
SuiteSSAClaims = "ssa-claims"
41-
)
42-
43-
func init() {
44-
environment.AddTestSuite(SuiteSSAClaims,
45-
config.WithHelmInstallOpts(
46-
helm.WithArgs("--set args={--debug,--enable-ssa-claims}"),
47-
),
48-
config.WithLabelsToSelect(features.Labels{
49-
config.LabelTestSuite: []string{SuiteSSAClaims, config.TestSuiteDefault},
50-
}),
51-
)
52-
}
53-
5437
// LabelAreaAPIExtensions is applied to all features pertaining to API
5538
// extensions (i.e. Composition, XRDs, etc).
5639
const LabelAreaAPIExtensions = "apiextensions"
@@ -242,14 +225,11 @@ func TestPropagateFieldsRemovalToXR(t *testing.T) {
242225
manifests := "test/e2e/manifests/apiextensions/composition/propagate-field-removals"
243226
environment.Test(t,
244227
features.NewWithDescription(t.Name(), "Tests that field removals in a claim are correctly propagated to the associated composite resource (XR), ensuring that updates and deletions are properly synchronized, and that the status from the XR is accurately reflected back to the claim.").
228+
WithLabel(LabelStage, LabelStageBeta).
245229
WithLabel(LabelArea, LabelAreaAPIExtensions).
246230
WithLabel(LabelSize, LabelSizeSmall).
247231
WithLabel(LabelModifyCrossplaneInstallation, LabelModifyCrossplaneInstallationTrue).
248-
WithLabel(config.LabelTestSuite, SuiteSSAClaims).
249-
WithSetup("EnableSSAClaims", funcs.AllOf(
250-
funcs.AsFeaturesFunc(environment.HelmUpgradeCrossplaneToSuite(SuiteSSAClaims)),
251-
funcs.ReadyToTestWithin(1*time.Minute, namespace),
252-
)).
232+
WithLabel(config.LabelTestSuite, config.TestSuiteDefault).
253233
WithSetup("PrerequisitesAreCreated", funcs.AllOf(
254234
funcs.ApplyResources(FieldManager, manifests, "setup/*.yaml"),
255235
funcs.ResourcesCreatedWithin(30*time.Second, manifests, "setup/*.yaml"),
@@ -284,10 +264,6 @@ func TestPropagateFieldsRemovalToXR(t *testing.T) {
284264
funcs.ResourcesDeletedWithin(2*time.Minute, manifests, "claim.yaml"),
285265
)).
286266
WithTeardown("DeletePrerequisites", funcs.ResourcesDeletedAfterListedAreGone(3*time.Minute, manifests, "setup/*.yaml", nopList)).
287-
WithTeardown("DisableSSAClaims", funcs.AllOf(
288-
funcs.AsFeaturesFunc(environment.HelmUpgradeCrossplaneToBase()), // Disable our feature flag.
289-
funcs.ReadyToTestWithin(1*time.Minute, namespace),
290-
)).
291267
Feature(),
292268
)
293269
}
@@ -296,15 +272,16 @@ func TestPropagateFieldsRemovalToXRAfterUpgrade(t *testing.T) {
296272
manifests := "test/e2e/manifests/apiextensions/composition/propagate-field-removals"
297273
environment.Test(t,
298274
features.NewWithDescription(t.Name(), "Tests that field removals in a composite resource (XR) are correctly propagated after upgrading the field managers from CSA to SSA, verifying that the upgrade process does not interfere with the synchronization of fields between the claim and the XR.").
275+
WithLabel(LabelStage, LabelStageBeta).
299276
WithLabel(LabelArea, LabelAreaAPIExtensions).
300277
WithLabel(LabelSize, LabelSizeSmall).
301278
WithLabel(LabelModifyCrossplaneInstallation, LabelModifyCrossplaneInstallationTrue).
302-
WithLabel(config.LabelTestSuite, SuiteSSAClaims).
303-
// SSA claims are always enabled in this test suite, so we need to
304-
// explicitly disable them first before we create anything.
279+
WithLabel(config.LabelTestSuite, config.TestSuiteDefault).
280+
// SSA claims are enabled by default, so we need to explicitly
281+
// disable them first before we create anything.
305282
WithSetup("DisableSSAClaims", funcs.AllOf(
306-
funcs.AsFeaturesFunc(environment.HelmUpgradeCrossplaneToSuite(config.TestSuiteDefault)), // Disable our feature flag.
307-
funcs.ArgUnsetWithin(1*time.Minute, "--enable-ssa-claims", namespace, "crossplane"),
283+
funcs.AsFeaturesFunc(environment.HelmUpgradeCrossplaneToBase(helm.WithArgs("--set args={--debug,--enable-ssa-claims=false}"))), // Disable our feature flag.
284+
funcs.ArgExistsWithin(1*time.Minute, "--enable-ssa-claims=false", namespace, "crossplane"),
308285
funcs.ReadyToTestWithin(1*time.Minute, namespace),
309286
funcs.DeploymentPodIsRunningMustNotChangeWithin(10*time.Second, namespace, "crossplane"),
310287
)).
@@ -324,8 +301,8 @@ func TestPropagateFieldsRemovalToXRAfterUpgrade(t *testing.T) {
324301
// field managers from CSA to SSA. If we didn't upgrade successfully
325302
// would end up sharing ownership with the old CSA field manager.
326303
Assess("EnableSSAClaims", funcs.AllOf(
327-
funcs.AsFeaturesFunc(environment.HelmUpgradeCrossplaneToSuite(SuiteSSAClaims)),
328-
funcs.ArgSetWithin(1*time.Minute, "--enable-ssa-claims", namespace, "crossplane"),
304+
funcs.AsFeaturesFunc(environment.HelmUpgradeCrossplaneToBase()),
305+
funcs.ArgNotExistsWithin(1*time.Minute, "--enable-ssa-claims=false", namespace, "crossplane"),
329306
funcs.ReadyToTestWithin(1*time.Minute, namespace),
330307
funcs.DeploymentPodIsRunningMustNotChangeWithin(10*time.Second, namespace, "crossplane"),
331308
)).
@@ -356,10 +333,6 @@ func TestPropagateFieldsRemovalToXRAfterUpgrade(t *testing.T) {
356333
funcs.ResourcesDeletedWithin(2*time.Minute, manifests, "claim.yaml"),
357334
)).
358335
WithTeardown("DeletePrerequisites", funcs.ResourcesDeletedAfterListedAreGone(3*time.Minute, manifests, "setup/*.yaml", nopList)).
359-
WithTeardown("DisableSSAClaims", funcs.AllOf(
360-
funcs.AsFeaturesFunc(environment.HelmUpgradeCrossplaneToBase()), // Disable our feature flag.
361-
funcs.ReadyToTestWithin(1*time.Minute, namespace),
362-
)).
363336
Feature(),
364337
)
365338
}
@@ -368,14 +341,11 @@ func TestPropagateFieldsRemovalToComposed(t *testing.T) {
368341
manifests := "test/e2e/manifests/apiextensions/composition/propagate-field-removals"
369342
environment.Test(t,
370343
features.NewWithDescription(t.Name(), "Tests Crossplane's end-to-end SSA syncing functionality of clear propagation of fields from claim->XR->MR, when existing composition and resources are migrated from native P-and-T to functions pipeline mode.").
344+
WithLabel(LabelStage, LabelStageBeta).
371345
WithLabel(LabelArea, LabelAreaAPIExtensions).
372346
WithLabel(LabelSize, LabelSizeSmall).
373347
WithLabel(LabelModifyCrossplaneInstallation, LabelModifyCrossplaneInstallationTrue).
374-
WithLabel(config.LabelTestSuite, SuiteSSAClaims).
375-
WithSetup("EnableSSAClaims", funcs.AllOf(
376-
funcs.AsFeaturesFunc(environment.HelmUpgradeCrossplaneToSuite(SuiteSSAClaims)),
377-
funcs.ReadyToTestWithin(1*time.Minute, namespace),
378-
)).
348+
WithLabel(config.LabelTestSuite, config.TestSuiteDefault).
379349
WithSetup("PrerequisitesAreCreated", funcs.AllOf(
380350
funcs.ApplyResources(FieldManager, manifests, "setup/*.yaml"),
381351
funcs.ResourcesCreatedWithin(30*time.Second, manifests, "setup/*.yaml"),
@@ -402,10 +372,6 @@ func TestPropagateFieldsRemovalToComposed(t *testing.T) {
402372
funcs.ResourcesDeletedWithin(2*time.Minute, manifests, "claim.yaml"),
403373
)).
404374
WithTeardown("DeletePrerequisites", funcs.ResourcesDeletedAfterListedAreGone(3*time.Minute, manifests, "setup/*.yaml", nopList)).
405-
WithTeardown("DisableSSAClaims", funcs.AllOf(
406-
funcs.AsFeaturesFunc(environment.HelmUpgradeCrossplaneToBase()), // Disable our feature flag.
407-
funcs.ReadyToTestWithin(1*time.Minute, namespace),
408-
)).
409375
Feature(),
410376
)
411377
}
@@ -414,14 +380,11 @@ func TestCompositionSelection(t *testing.T) {
414380
manifests := "test/e2e/manifests/apiextensions/composition/composition-selection"
415381
environment.Test(t,
416382
features.NewWithDescription(t.Name(), "Tests that label selectors in a claim are correctly propagated to the composite resource (XR), ensuring that the appropriate composition is selected and remains consistent even after updates to the label selectors.").
383+
WithLabel(LabelStage, LabelStageBeta).
417384
WithLabel(LabelArea, LabelAreaAPIExtensions).
418385
WithLabel(LabelSize, LabelSizeSmall).
419386
WithLabel(LabelModifyCrossplaneInstallation, LabelModifyCrossplaneInstallationTrue).
420-
WithLabel(config.LabelTestSuite, SuiteSSAClaims).
421-
WithSetup("EnableSSAClaims", funcs.AllOf(
422-
funcs.AsFeaturesFunc(environment.HelmUpgradeCrossplaneToSuite(SuiteSSAClaims)),
423-
funcs.ReadyToTestWithin(1*time.Minute, namespace),
424-
)).
387+
WithLabel(config.LabelTestSuite, config.TestSuiteDefault).
425388
WithSetup("PrerequisitesAreCreated", funcs.AllOf(
426389
funcs.ApplyResources(FieldManager, manifests, "setup/*.yaml"),
427390
funcs.ResourcesCreatedWithin(30*time.Second, manifests, "setup/*.yaml"),
@@ -461,10 +424,6 @@ func TestCompositionSelection(t *testing.T) {
461424
funcs.ResourcesDeletedWithin(2*time.Minute, manifests, "claim.yaml"),
462425
)).
463426
WithTeardown("DeletePrerequisites", funcs.ResourcesDeletedAfterListedAreGone(3*time.Minute, manifests, "setup/*.yaml", nopList)).
464-
WithTeardown("DisableSSAClaims", funcs.AllOf(
465-
funcs.AsFeaturesFunc(environment.HelmUpgradeCrossplaneToBase()), // Disable our feature flag.
466-
funcs.ReadyToTestWithin(1*time.Minute, namespace),
467-
)).
468427
Feature(),
469428
)
470429
}

test/e2e/config/environment.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@ func (e *Environment) HelmUpgradeCrossplaneToSuite(suite string, extra ...helm.O
180180

181181
// HelmUpgradeCrossplaneToBase returns a features.Func that upgrades crossplane using
182182
// the specified suite's helm install options.
183-
func (e *Environment) HelmUpgradeCrossplaneToBase() env.Func {
184-
return e.HelmUpgradeCrossplaneToSuite(e.selectedTestSuite.String())
183+
func (e *Environment) HelmUpgradeCrossplaneToBase(extra ...helm.Option) env.Func {
184+
return e.HelmUpgradeCrossplaneToSuite(e.selectedTestSuite.String(), extra...)
185185
}
186186

187187
// HelmInstallBaseCrossplane returns a features.Func that installs crossplane using

test/e2e/funcs/feature.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -171,27 +171,27 @@ func DeploymentPodIsRunningMustNotChangeWithin(d time.Duration, namespace, name
171171
}
172172
}
173173

174-
// ArgSetWithin fails a test if the supplied Deployment does not have a Pod with
175-
// the given argument set within the supplied duration.
176-
func ArgSetWithin(d time.Duration, arg, namespace, name string) features.Func {
177-
return checkArgSetWithin(d, arg, true, namespace, name)
174+
// ArgExistsWithin fails a test if the supplied Deployment does not have a Pod with
175+
// the given argument within the supplied duration.
176+
func ArgExistsWithin(d time.Duration, arg, namespace, name string) features.Func {
177+
return checkArgExistsWithin(d, arg, true, namespace, name)
178178
}
179179

180-
// ArgUnsetWithin fails a test if the supplied Deployment does not have a Pod with
181-
// the given argument unset within the supplied duration.
182-
func ArgUnsetWithin(d time.Duration, arg, namespace, name string) features.Func {
183-
return checkArgSetWithin(d, arg, false, namespace, name)
180+
// ArgNotExistsWithin fails a test if the supplied Deployment does not have a Pod with
181+
// the given argument not existing within the supplied duration.
182+
func ArgNotExistsWithin(d time.Duration, arg, namespace, name string) features.Func {
183+
return checkArgExistsWithin(d, arg, false, namespace, name)
184184
}
185185

186-
// checkArgSetWithin implements a check for the supplied Deployment having a Pod
187-
// with the given argument being either set or unset within the supplied
186+
// checkArgExistsWithin implements a check for the supplied Deployment having a Pod
187+
// with the given argument either existing or not existing within the supplied
188188
// duration.
189-
func checkArgSetWithin(d time.Duration, arg string, wantSet bool, namespace, name string) features.Func {
189+
func checkArgExistsWithin(d time.Duration, arg string, wantExist bool, namespace, name string) features.Func {
190190
return func(ctx context.Context, t *testing.T, c *envconf.Config) context.Context {
191191
t.Helper()
192192

193193
dp := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: name}}
194-
t.Logf("Waiting %s for pod in deployment %s/%s to have arg %s set=%t...", d, dp.GetNamespace(), dp.GetName(), arg, wantSet)
194+
t.Logf("Waiting %s for pod in deployment %s/%s to have arg %s exist=%t...", d, dp.GetNamespace(), dp.GetName(), arg, wantExist)
195195
start := time.Now()
196196

197197
if err := wait.For(func(ctx context.Context) (done bool, err error) {
@@ -210,10 +210,10 @@ func checkArgSetWithin(d time.Duration, arg string, wantSet bool, namespace, nam
210210
}
211211

212212
switch {
213-
case wantSet && !found:
213+
case wantExist && !found:
214214
t.Logf("did not find arg %s within %s", arg, c.Args)
215215
return false, nil
216-
case !wantSet && found:
216+
case !wantExist && found:
217217
t.Logf("unexpectedly found arg %s within %s", arg, c.Args)
218218
return false, nil
219219
default:
@@ -224,7 +224,7 @@ func checkArgSetWithin(d time.Duration, arg string, wantSet bool, namespace, nam
224224
return ctx
225225
}
226226

227-
t.Logf("Deployment %s/%s has pod with arg %s set=%t after %s", dp.GetNamespace(), dp.GetName(), arg, wantSet, since(start))
227+
t.Logf("Deployment %s/%s has pod with arg %s exist=%t after %s", dp.GetNamespace(), dp.GetName(), arg, wantExist, since(start))
228228
return ctx
229229
}
230230
}

0 commit comments

Comments
 (0)