Skip to content

Commit 1de8ff1

Browse files
Fix SA1019: server-side apply required, needs generated apply configurations
1 parent 10c2841 commit 1de8ff1

File tree

1 file changed

+22
-30
lines changed

1 file changed

+22
-30
lines changed

internal/operator-controller/applier/boxcutter.go

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import (
1919
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2020
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2121
"k8s.io/apimachinery/pkg/runtime"
22+
"k8s.io/apimachinery/pkg/types"
23+
"k8s.io/apimachinery/pkg/util/json"
2224
"k8s.io/apiserver/pkg/authentication/user"
2325
"k8s.io/apiserver/pkg/authorization/authorizer"
2426
"k8s.io/cli-runtime/pkg/printers"
@@ -41,6 +43,20 @@ const (
4143
ClusterExtensionRevisionRetentionLimit = 5
4244
)
4345

46+
// serverSideApplyPatch implements the Server-Side Apply patch type.
47+
// This replaces the deprecated client.Apply variable by creating the patch type directly.
48+
type serverSideApplyPatch struct{}
49+
50+
// Type implements client.Patch interface.
51+
func (p serverSideApplyPatch) Type() types.PatchType {
52+
return types.ApplyPatchType
53+
}
54+
55+
// Data implements client.Patch interface.
56+
func (p serverSideApplyPatch) Data(obj client.Object) ([]byte, error) {
57+
return json.Marshal(obj)
58+
}
59+
4460
type ClusterExtensionRevisionGenerator interface {
4561
GenerateRevision(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1.ClusterExtensionRevision, error)
4662
GenerateRevisionFromHelmRelease(
@@ -439,37 +455,13 @@ func (bc *Boxcutter) createOrUpdate(ctx context.Context, user user.Info, rev *oc
439455
return err
440456
}
441457

442-
// DEPRECATION NOTICE: Using client.Apply (deprecated in controller-runtime v0.23.0+)
443-
//
444-
// WHY WE CAN'T FIX THIS YET:
445-
// The recommended replacement is the new typed Apply() method that requires generated
446-
// apply configurations (ApplyConfiguration types). However, this project does not
447-
// currently generate these apply configurations for its API types.
448-
//
449-
// WHY WE NEED SERVER-SIDE APPLY SEMANTICS:
450-
// This controller requires server-side apply with field ownership management to:
451-
// 1. Track which controller owns which fields (via client.FieldOwner)
452-
// 2. Take ownership of fields from other managers during upgrades (via client.ForceOwnership)
453-
// 3. Automatically create-or-update without explicit Get/Create/Update logic
454-
//
455-
// WHY ALTERNATIVES DON'T WORK:
456-
// - client.MergeFrom(): Lacks field ownership - causes conflicts during controller upgrades
457-
// - client.StrategicMergePatch(): No field management - upgrade tests fail with ownership errors
458-
// - Manual Create/Update: Loses server-side apply benefits, complex to implement correctly
459-
//
460-
// WHAT'S REQUIRED TO FIX PROPERLY:
461-
// 1. Generate apply configurations for all API types (ClusterExtensionRevision, etc.)
462-
// - Requires running controller-gen with --with-applyconfig flag
463-
// - Generates ClusterExtensionRevisionApplyConfiguration types
464-
// 2. Update all resource creation/update code to use typed Apply methods
465-
// 3. Update all tests to work with new patterns
466-
// This is a project-wide effort beyond the scope of the k8s v1.35 upgrade.
467-
//
468-
// MIGRATION PATH:
469-
// Track in a future issue: "Generate apply configurations and migrate to typed Apply methods"
458+
// Use Server-Side Apply via client.Patch() with serverSideApplyPatch.
459+
// This provides field ownership management and conflict resolution required for OLM upgrades.
470460
//
471-
// nolint:staticcheck // SA1019: server-side apply required, needs generated apply configurations
472-
return bc.Client.Patch(ctx, rev, client.Apply, client.FieldOwner(bc.FieldOwner), client.ForceOwnership)
461+
// We use a custom serverSideApplyPatch type instead of the deprecated client.Apply variable.
462+
// The alternative client.Client.Apply() method requires generated runtime.ApplyConfiguration types,
463+
// which are not standard for Kubebuilder CRDs.
464+
return bc.Client.Patch(ctx, rev, serverSideApplyPatch{}, client.FieldOwner(bc.FieldOwner), client.ForceOwnership)
473465
}
474466

475467
func (bc *Boxcutter) Apply(ctx context.Context, contentFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (bool, string, error) {

0 commit comments

Comments
 (0)