Skip to content

Commit 7746ba4

Browse files
committed
Use server-side apply for e2e CreateOrUpdate
1 parent 55e16f4 commit 7746ba4

File tree

2 files changed

+11
-41
lines changed

2 files changed

+11
-41
lines changed

test/e2e/clusterctl_upgrade.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ func ClusterctlUpgradeSpec(ctx context.Context, inputGetter func() ClusterctlUpg
454454
// Applying the cluster template in dry-run to ensure mgmt cluster webhooks are up and available
455455
log.Logf("Applying the cluster template yaml to the cluster in dry-run")
456456
Eventually(func() error {
457-
return managementClusterProxy.CreateOrUpdate(ctx, workloadClusterTemplate, framework.WithCreateOpts([]client.CreateOption{client.DryRunAll}...), framework.WithUpdateOpts([]client.UpdateOption{client.DryRunAll}...))
457+
return managementClusterProxy.CreateOrUpdate(ctx, workloadClusterTemplate, framework.WithPatchOpts([]client.PatchOption{client.DryRunAll}...))
458458
}, "1m", "10s").ShouldNot(HaveOccurred())
459459

460460
log.Logf("Applying the cluster template yaml to the cluster")

test/framework/cluster_proxy.go

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,8 @@ import (
3030
. "github.com/onsi/ginkgo/v2"
3131
. "github.com/onsi/gomega"
3232
corev1 "k8s.io/api/core/v1"
33-
apierrors "k8s.io/apimachinery/pkg/api/errors"
34-
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3533
"k8s.io/apimachinery/pkg/labels"
3634
"k8s.io/apimachinery/pkg/runtime"
37-
"k8s.io/apimachinery/pkg/types"
3835
kerrors "k8s.io/apimachinery/pkg/util/errors"
3936
"k8s.io/apimachinery/pkg/util/wait"
4037
"k8s.io/client-go/kubernetes"
@@ -108,8 +105,7 @@ type ClusterProxy interface {
108105
// createOrUpdateConfig contains options for use with CreateOrUpdate.
109106
type createOrUpdateConfig struct {
110107
labelSelector labels.Selector
111-
createOpts []client.CreateOption
112-
updateOpts []client.UpdateOption
108+
patchOpts []client.PatchOption
113109
}
114110

115111
// CreateOrUpdateOption is a configuration option supplied to CreateOrUpdate.
@@ -122,17 +118,10 @@ func WithLabelSelector(labelSelector labels.Selector) CreateOrUpdateOption {
122118
}
123119
}
124120

125-
// WithCreateOpts allows definition of the Create options to be used in resource Create.
126-
func WithCreateOpts(createOpts ...client.CreateOption) CreateOrUpdateOption {
121+
// WithPatchOpts allows definition of the Patch options to be used in resource Patch.
122+
func WithPatchOpts(patchOpts ...client.PatchOption) CreateOrUpdateOption {
127123
return func(c *createOrUpdateConfig) {
128-
c.createOpts = createOpts
129-
}
130-
}
131-
132-
// WithUpdateOpts allows definition of the Update options to be used in resource Update.
133-
func WithUpdateOpts(updateOpts ...client.UpdateOption) CreateOrUpdateOption {
134-
return func(c *createOrUpdateConfig) {
135-
c.updateOpts = updateOpts
124+
c.patchOpts = patchOpts
136125
}
137126
}
138127

@@ -306,8 +295,9 @@ func (p *clusterProxy) GetCache(ctx context.Context) cache.Cache {
306295
return p.cache
307296
}
308297

309-
// CreateOrUpdate creates or updates objects using the clusterProxy client.
310-
// Defaults to use FieldValidation: strict, which can be overwritten with CreateOrUpdateOptions.
298+
// CreateOrUpdate creates or updates objects using the clusterProxy client using server-side apply.
299+
// Defaults to use FieldValidation: strict and FieldManager: cluster-api-e2e,
300+
// which can be overwritten with CreateOrUpdateOptions.
311301
func (p *clusterProxy) CreateOrUpdate(ctx context.Context, resources []byte, opts ...CreateOrUpdateOption) error {
312302
Expect(ctx).NotTo(BeNil(), "ctx is required for CreateOrUpdate")
313303
Expect(resources).NotTo(BeNil(), "resources is required for CreateOrUpdate")
@@ -320,38 +310,18 @@ func (p *clusterProxy) CreateOrUpdate(ctx context.Context, resources []byte, opt
320310
labelSelector = config.labelSelector
321311
}
322312
// Prepending field validation strict so that it is used per default, but can still be overwritten.
323-
config.createOpts = append([]client.CreateOption{client.FieldValidation("Strict")}, config.createOpts...)
324-
config.updateOpts = append([]client.UpdateOption{client.FieldValidation("Strict")}, config.updateOpts...)
313+
config.patchOpts = append([]client.PatchOption{client.FieldValidation("Strict"), client.FieldOwner("cluster-api-e2e")}, config.patchOpts...)
325314
objs, err := yaml.ToUnstructured(resources)
326315
if err != nil {
327316
return err
328317
}
329318

330-
existingObject := &unstructured.Unstructured{}
331319
var retErrs []error
332320
for _, o := range objs {
333-
objectKey := types.NamespacedName{
334-
Name: o.GetName(),
335-
Namespace: o.GetNamespace(),
336-
}
337-
existingObject.SetAPIVersion(o.GetAPIVersion())
338-
existingObject.SetKind(o.GetKind())
339321
labels := labels.Set(o.GetLabels())
340322
if labelSelector.Matches(labels) {
341-
if err := p.GetClient().Get(ctx, objectKey, existingObject); err != nil {
342-
// Expected error -- if the object does not exist, create it
343-
if apierrors.IsNotFound(err) {
344-
if err := p.GetClient().Create(ctx, &o, config.createOpts...); err != nil {
345-
retErrs = append(retErrs, err)
346-
}
347-
} else {
348-
retErrs = append(retErrs, err)
349-
}
350-
} else {
351-
o.SetResourceVersion(existingObject.GetResourceVersion())
352-
if err := p.GetClient().Update(ctx, &o, config.updateOpts...); err != nil {
353-
retErrs = append(retErrs, err)
354-
}
323+
if err := p.GetClient().Patch(ctx, &o, client.Apply, config.patchOpts...); err != nil {
324+
retErrs = append(retErrs, err)
355325
}
356326
}
357327
}

0 commit comments

Comments
 (0)