diff --git a/util/conditions/v1beta2/patch.go b/util/conditions/v1beta2/patch.go index 1be0f63f4d8f..8fd76c4123f4 100644 --- a/util/conditions/v1beta2/patch.go +++ b/util/conditions/v1beta2/patch.go @@ -23,7 +23,6 @@ import ( "github.com/pkg/errors" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/cluster-api/util" ) @@ -53,24 +52,18 @@ const ( ) // NewPatch returns the Patch required to align source conditions to after conditions. -func NewPatch(before, after runtime.Object) (Patch, error) { +func NewPatch(before, after Getter) (Patch, error) { var patch Patch if util.IsNil(before) { return nil, errors.New("error creating patch: before object is nil") } - beforeConditions, err := GetAll(before) - if err != nil { - return nil, errors.Wrap(err, "error creating patch: failed to get conditions from before object") - } + beforeConditions := before.GetV1Beta2Conditions() if util.IsNil(after) { return nil, errors.New("error creating patch: after object is nil") } - afterConditions, err := GetAll(after) - if err != nil { - return nil, errors.Wrap(err, "error creating patch: failed to get conditions from after object") - } + afterConditions := after.GetV1Beta2Conditions() // Identify AddCondition and ModifyCondition changes. for i := range afterConditions { @@ -117,7 +110,7 @@ type ApplyOption func(*applyOptions) // Apply executes a three-way merge of a list of Patch. // When merge conflicts are detected (latest deviated from before in an incompatible way), an error is returned. -func (p Patch) Apply(latest runtime.Object, options ...ApplyOption) error { +func (p Patch) Apply(latest Setter, options ...ApplyOption) error { if p.IsZero() { return nil } @@ -125,10 +118,7 @@ func (p Patch) Apply(latest runtime.Object, options ...ApplyOption) error { if util.IsNil(latest) { return errors.New("error patching conditions: latest object is nil") } - latestConditions, err := GetAll(latest) - if err != nil { - return errors.Wrap(err, "error creating patch: failed to get conditions from latest object") - } + latestConditions := latest.GetV1Beta2Conditions() applyOpt := &applyOptions{} for _, o := range options { @@ -211,7 +201,8 @@ func (p Patch) Apply(latest runtime.Object, options ...ApplyOption) error { } } - return SetAll(latest, latestConditions) + latest.SetV1Beta2Conditions(latestConditions) + return nil } // IsZero returns true if the patch is nil or has no changes. diff --git a/util/conditions/v1beta2/patch_test.go b/util/conditions/v1beta2/patch_test.go index 38b61a8886d3..aebfda081b14 100644 --- a/util/conditions/v1beta2/patch_test.go +++ b/util/conditions/v1beta2/patch_test.go @@ -21,7 +21,6 @@ import ( . "github.com/onsi/gomega" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/cluster-api/internal/test/builder" ) @@ -32,8 +31,8 @@ func TestNewPatch(t *testing.T) { tests := []struct { name string - before runtime.Object - after runtime.Object + before Setter + after Setter want Patch wantErr bool }{ @@ -136,9 +135,9 @@ func TestApply(t *testing.T) { tests := []struct { name string - before runtime.Object - after runtime.Object - latest runtime.Object + before Setter + after Setter + latest Setter options []ApplyOption want []metav1.Condition wantErr bool @@ -343,21 +342,19 @@ func TestApply(t *testing.T) { } g.Expect(err).ToNot(HaveOccurred()) - gotConditions, err := GetAll(tt.latest) - g.Expect(err).ToNot(HaveOccurred()) - + gotConditions := tt.latest.GetV1Beta2Conditions() g.Expect(gotConditions).To(MatchConditions(tt.want)) }) } } -func objectWithConditions(conditions ...metav1.Condition) runtime.Object { +func objectWithConditions(conditions ...metav1.Condition) Setter { obj := &builder.Phase3Obj{} obj.Status.Conditions = conditions return obj } -func nilObject() runtime.Object { - var obj runtime.Object +func nilObject() Setter { + var obj *builder.Phase3Obj return obj } diff --git a/util/patch/options.go b/util/patch/options.go index 640446681ed1..a42c7d9c8a6d 100644 --- a/util/patch/options.go +++ b/util/patch/options.go @@ -41,6 +41,16 @@ type HelperOptions struct { // OwnedV1Beta2Conditions defines condition types owned by the controller. // In case of conflicts for the owned conditions, the patch helper will always use the value provided by the controller. OwnedV1Beta2Conditions []string + + // Metav1ConditionsFields allows to override the path for the field hosting []metav1.Condition. + // Please note that the default value for this option is inferred from the object struct. + // The override for this option is considered only if the object implements the v1beta2conditions.Setter interface. + Metav1ConditionsFieldPath []string + + // Clusterv1ConditionsFieldPath allows to override the path for the field hosting clusterv1.Conditions. + // Please note that the default value for this option is inferred from the object struct. + // The override for this option is considered only if the object implements the conditions.Setter interface. + Clusterv1ConditionsFieldPath []string } // WithForceOverwriteConditions allows the patch helper to overwrite conditions in case of conflicts. @@ -82,3 +92,23 @@ type WithOwnedV1Beta2Conditions struct { func (w WithOwnedV1Beta2Conditions) ApplyToHelper(in *HelperOptions) { in.OwnedV1Beta2Conditions = w.Conditions } + +// Metav1ConditionsFieldPath allows to override the path for the field hosting []metav1.Condition. +// Please note that the default value for this option is inferred from the object struct. +// The override for this option is considered only if the object implements the v1beta2conditions.Setter interface. +type Metav1ConditionsFieldPath []string + +// ApplyToHelper applies this configuration to the given HelperOptions. +func (w Metav1ConditionsFieldPath) ApplyToHelper(in *HelperOptions) { + in.Metav1ConditionsFieldPath = w +} + +// Clusterv1ConditionsFieldPath allows to override the path for the field hosting clusterv1.Conditions. +// Please note that the default value for this option is inferred from the object struct. +// The override for this option is considered only if the object implements the conditions.Setter interface. +type Clusterv1ConditionsFieldPath []string + +// ApplyToHelper applies this configuration to the given HelperOptions. +func (w Clusterv1ConditionsFieldPath) ApplyToHelper(in *HelperOptions) { + in.Clusterv1ConditionsFieldPath = w +} diff --git a/util/patch/patch.go b/util/patch/patch.go index 26a87a13882d..4788ea2e3759 100644 --- a/util/patch/patch.go +++ b/util/patch/patch.go @@ -48,12 +48,22 @@ type Helper struct { after *unstructured.Unstructured changes sets.Set[string] - metav1ConditionsFields []string - clusterv1ConditionsFields []string + metav1ConditionsFieldPath []string + clusterv1ConditionsFieldPath []string } // NewHelper returns an initialized Helper. Use NewHelper before changing // obj. After changing obj use Helper.Patch to persist your changes. +// +// Please note that patch helper implements a custom handling for objects implementing +// the condition.Setter interface or the v1beta2conditions.Setter interface. +// +// It is also possible to implement wrappers for object not implementing those interfaces; +// in case those objects have custom conditions types the wrapper should take care of conversions. +// Additionally, if the conditions are not in the canonical place defined by the proposal for +// improving status in Cluster API conditions, locations of the condition field must be +// provided explicitly by using Metav1ConditionsFieldPath and Clusterv1ConditionsFieldPath options +// during the Patch call. func NewHelper(obj client.Object, crClient client.Client) (*Helper, error) { // Return early if the object is nil. if util.IsNil(obj) { @@ -67,17 +77,19 @@ func NewHelper(obj client.Object, crClient client.Client) (*Helper, error) { return nil, errors.Wrapf(err, "failed to create patch helper for object %s", klog.KObj(obj)) } - metav1ConditionsFields, clusterv1ConditionsFields, err := identifySupportedConditions(obj) + // Identify location of the condition fields according to the canonical place defined by the proposal for + // // improving status in Cluster API conditions. + metav1ConditionsFieldPath, clusterv1ConditionsFieldPath, err := identifyConditionsFieldsPath(obj) if err != nil { return nil, errors.Wrapf(err, "failed to identify condition fields for object %s", klog.KObj(obj)) } // Check if the object satisfies the Cluster API conditions contract; if not, ignore condition fields for clusterv1.Conditions. if _, canInterfaceConditions := obj.(conditions.Setter); !canInterfaceConditions { - clusterv1ConditionsFields = nil + clusterv1ConditionsFieldPath = nil } if _, canInterfaceConditions := obj.(conditions.Getter); !canInterfaceConditions { - clusterv1ConditionsFields = nil + clusterv1ConditionsFieldPath = nil } // Convert the object to unstructured to compare against our before copy. @@ -87,12 +99,12 @@ func NewHelper(obj client.Object, crClient client.Client) (*Helper, error) { } return &Helper{ - client: crClient, - gvk: gvk, - before: unstructuredObj, - beforeObject: obj.DeepCopyObject().(client.Object), - metav1ConditionsFields: metav1ConditionsFields, - clusterv1ConditionsFields: clusterv1ConditionsFields, + client: crClient, + gvk: gvk, + before: unstructuredObj, + beforeObject: obj.DeepCopyObject().(client.Object), + metav1ConditionsFieldPath: metav1ConditionsFieldPath, + clusterv1ConditionsFieldPath: clusterv1ConditionsFieldPath, }, nil } @@ -118,6 +130,22 @@ func (h *Helper) Patch(ctx context.Context, obj client.Object, opts ...Option) e opt.ApplyToHelper(options) } + // If condition field path override have been provided, propagate them to the helper for usage in various places of this func. + if len(options.Clusterv1ConditionsFieldPath) > 0 { + h.clusterv1ConditionsFieldPath = nil + } + if len(options.Metav1ConditionsFieldPath) > 0 { + h.metav1ConditionsFieldPath = nil + } + + // Check if the object satisfies the Cluster API contract setter interfaces; if not, ignore condition field path entirely. + if _, canInterfaceConditions := obj.(conditions.Setter); !canInterfaceConditions { + h.clusterv1ConditionsFieldPath = nil + } + if _, canInterfaceV1Beta2Conditions := obj.(v1beta2conditions.Setter); !canInterfaceV1Beta2Conditions { + h.metav1ConditionsFieldPath = nil + } + // Convert the object to unstructured to compare against our before copy. h.after, err = toUnstructured(obj, gvk) if err != nil { @@ -207,24 +235,24 @@ func (h *Helper) patchStatus(ctx context.Context, obj client.Object) error { // no unresolvable conflicts, the patch is sent again. func (h *Helper) patchStatusConditions(ctx context.Context, obj client.Object, forceOverwrite bool, ownedConditions []clusterv1.ConditionType, ownedV1beta2Conditions []string) error { // Nothing to do if the object doesn't have conditions (doesn't have conditions identified as needing a special treatment). - if len(h.clusterv1ConditionsFields) == 0 && len(h.metav1ConditionsFields) == 0 { + if len(h.clusterv1ConditionsFieldPath) == 0 && len(h.metav1ConditionsFieldPath) == 0 { return nil } // If the object has clusterv1 conditions, create a function applying corresponding changes if any. var clusterv1ApplyPatch func(client.Object) error - if len(h.clusterv1ConditionsFields) > 0 { + if len(h.clusterv1ConditionsFieldPath) > 0 { // Make sure our before/after objects satisfy the proper interface before continuing. // // NOTE: The checks and error below are done so that we don't panic if any of the objects don't satisfy the // interface any longer, although this shouldn't happen because we already check when creating the patcher. - before, ok := h.beforeObject.(conditions.Getter) + before, ok := h.beforeObject.(conditions.Setter) if !ok { - return errors.Errorf("%s %s doesn't satisfy conditions.Getter, cannot patch", h.gvk.Kind, klog.KObj(before)) + return errors.Errorf("%s %s doesn't satisfy conditions.Getter, cannot patch", h.gvk.Kind, klog.KObj(h.beforeObject)) } - after, ok := obj.(conditions.Getter) + after, ok := obj.(conditions.Setter) if !ok { - return errors.Errorf("%s %s doesn't satisfy conditions.Getter, cannot compute patch", h.gvk.Kind, after.GetObjectKind()) + return errors.Errorf("%s %s doesn't satisfy conditions.Getter, cannot compute patch", h.gvk.Kind, klog.KObj(obj)) } diff, err := conditions.NewPatch( @@ -238,7 +266,7 @@ func (h *Helper) patchStatusConditions(ctx context.Context, obj client.Object, f clusterv1ApplyPatch = func(latest client.Object) error { latestSetter, ok := latest.(conditions.Setter) if !ok { - return errors.Errorf("%s %s doesn't satisfy conditions.Setter, cannot apply patch", h.gvk.Kind, before.GetObjectKind()) + return errors.Errorf("%s %s doesn't satisfy conditions.Setter, cannot apply patch", h.gvk.Kind, klog.KObj(latest)) } return diff.Apply(latestSetter, conditions.WithForceOverwrite(forceOverwrite), conditions.WithOwnedConditions(ownedConditions...)) @@ -248,10 +276,23 @@ func (h *Helper) patchStatusConditions(ctx context.Context, obj client.Object, f // If the object has metav1 conditions, create a function applying corresponding changes if any. var metav1ApplyPatch func(client.Object) error - if len(h.metav1ConditionsFields) > 0 { + if len(h.metav1ConditionsFieldPath) > 0 { + // Make sure our before/after objects satisfy the proper interface before continuing. + // + // NOTE: The checks and error below are done so that we don't panic if any of the objects don't satisfy the + // interface any longer, although this shouldn't happen because we already check when creating the patcher. + before, ok := h.beforeObject.(v1beta2conditions.Getter) + if !ok { + return errors.Errorf("%s %s doesn't satisfy v1beta2conditions.Getter, cannot patch", h.gvk.Kind, klog.KObj(h.beforeObject)) + } + after, ok := obj.(v1beta2conditions.Getter) + if !ok { + return errors.Errorf("%s %s doesn't satisfy v1beta2conditions.Getter, cannot compute patch", h.gvk.Kind, klog.KObj(obj)) + } + diff, err := v1beta2conditions.NewPatch( - h.beforeObject, - obj, + before, + after, ) if err != nil { return errors.Wrapf(err, "%s can not be patched", h.gvk.Kind) @@ -259,7 +300,12 @@ func (h *Helper) patchStatusConditions(ctx context.Context, obj client.Object, f if !diff.IsZero() { metav1ApplyPatch = func(latest client.Object) error { - return diff.Apply(latest, v1beta2conditions.ForceOverwrite(forceOverwrite), v1beta2conditions.OwnedConditionTypes(ownedV1beta2Conditions...)) + latestSetter, ok := latest.(v1beta2conditions.Setter) + if !ok { + return errors.Errorf("%s %s doesn't satisfy conditions.Setter, cannot apply patch", h.gvk.Kind, klog.KObj(latest)) + } + + return diff.Apply(latestSetter, v1beta2conditions.ForceOverwrite(forceOverwrite), v1beta2conditions.OwnedConditionTypes(ownedV1beta2Conditions...)) } } } @@ -326,8 +372,8 @@ func (h *Helper) patchStatusConditions(ctx context.Context, obj client.Object, f // calculatePatch returns the before/after objects to be given in a controller-runtime patch, scoped down to the absolute necessary. func (h *Helper) calculatePatch(afterObj client.Object, focus patchType) (client.Object, client.Object, error) { // Get a shallow unsafe copy of the before/after object in unstructured form. - before := unsafeUnstructuredCopy(h.before, focus, h.metav1ConditionsFields, h.clusterv1ConditionsFields) - after := unsafeUnstructuredCopy(h.after, focus, h.metav1ConditionsFields, h.clusterv1ConditionsFields) + before := unsafeUnstructuredCopy(h.before, focus, h.clusterv1ConditionsFieldPath, h.metav1ConditionsFieldPath) + after := unsafeUnstructuredCopy(h.after, focus, h.clusterv1ConditionsFieldPath, h.metav1ConditionsFieldPath) // We've now applied all modifications to local unstructured objects, // make copies of the original objects and convert them back. diff --git a/util/patch/patch_test.go b/util/patch/patch_test.go index 49271930970d..319ee3a203d9 100644 --- a/util/patch/patch_test.go +++ b/util/patch/patch_test.go @@ -1364,8 +1364,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Marking clusterv1.conditions and metav1.conditions Ready=True") conditions.MarkTrue(obj, clusterv1.ReadyCondition) - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj)).To(Succeed()) @@ -1409,8 +1408,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Marking clusterv1.conditions and metav1.conditions Test=False") conditions.MarkFalse(objCopy, clusterv1.ConditionType("Test"), "reason", clusterv1.ConditionSeverityInfo, "message") - err := v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Test", Status: metav1.ConditionFalse, Reason: "reason", Message: "message", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Test", Status: metav1.ConditionFalse, Reason: "reason", Message: "message", LastTransitionTime: now}) g.Expect(env.Status().Update(ctx, objCopy)).To(Succeed()) t.Log("Validating that the local object's resource version is behind") @@ -1422,8 +1420,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Marking clusterv1.conditions and metav1.conditions Ready=True") conditions.MarkTrue(obj, clusterv1.ReadyCondition) - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj)).To(Succeed()) @@ -1449,24 +1446,15 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { return false } - testV1Beta2ConditionCopy, err := v1beta2conditions.Get(objCopy, "Test") - if err != nil { - return false - } - testV1Beta2ConditionAfter, err := v1beta2conditions.Get(objAfter, "Test") - if err != nil { - return false - } + testV1Beta2ConditionCopy := v1beta2conditions.Get(objCopy, "Test") + testV1Beta2ConditionAfter := v1beta2conditions.Get(objAfter, "Test") ok, err = v1beta2conditions.MatchCondition(*testV1Beta2ConditionCopy).Match(*testV1Beta2ConditionAfter) if err != nil || !ok { return false } - readyV1Beta2Before, err := v1beta2conditions.Get(obj, "Ready") - if err != nil { - return false - } - readyV1Beta2After, err := v1beta2conditions.Get(objAfter, "Ready") + readyV1Beta2Before := v1beta2conditions.Get(obj, "Ready") + readyV1Beta2After := v1beta2conditions.Get(objAfter, "Ready") if err != nil { return false } @@ -1501,8 +1489,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Marking clusterv1.conditions and metav1.conditions Test=False") conditions.MarkFalse(objCopy, clusterv1.ConditionType("Test"), "reason", clusterv1.ConditionSeverityInfo, "message") - err := v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Test", Status: metav1.ConditionFalse, Reason: "reason", Message: "message", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Test", Status: metav1.ConditionFalse, Reason: "reason", Message: "message", LastTransitionTime: now}) g.Expect(env.Status().Update(ctx, objCopy)).To(Succeed()) t.Log("Validating that the local object's resource version is behind") @@ -1516,8 +1503,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { obj.Spec.Foo = "foo" obj.Status.Bar = "bat" conditions.MarkTrue(obj, clusterv1.ReadyCondition) - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj)).To(Succeed()) @@ -1544,27 +1530,15 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { return false } - testV1Beta2ConditionCopy, err := v1beta2conditions.Get(objCopy, "Test") - if err != nil { - return false - } - testV1Beta2ConditionAfter, err := v1beta2conditions.Get(objAfter, "Test") - if err != nil { - return false - } + testV1Beta2ConditionCopy := v1beta2conditions.Get(objCopy, "Test") + testV1Beta2ConditionAfter := v1beta2conditions.Get(objAfter, "Test") ok, err = v1beta2conditions.MatchCondition(*testV1Beta2ConditionCopy).Match(*testV1Beta2ConditionAfter) if err != nil || !ok { return false } - readyV1Beta2Before, err := v1beta2conditions.Get(obj, "Ready") - if err != nil { - return false - } - readyV1Beta2After, err := v1beta2conditions.Get(objAfter, "Ready") - if err != nil { - return false - } + readyV1Beta2Before := v1beta2conditions.Get(obj, "Ready") + readyV1Beta2After := v1beta2conditions.Get(objAfter, "Ready") ok, err = v1beta2conditions.MatchCondition(*readyV1Beta2Before).Match(*readyV1Beta2After) if err != nil || !ok { return false @@ -1643,8 +1617,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { objCopy := obj.DeepCopy() t.Log("Marking a Ready condition to be false") - err := v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) g.Expect(env.Status().Update(ctx, objCopy)).To(Succeed()) t.Log("Validating that the local object's resource version is behind") @@ -1655,8 +1628,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) t.Log("Marking condition Ready=True") - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj)).NotTo(Succeed()) @@ -1693,8 +1665,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Marking a Ready clusterv1.condition and metav1.conditions to be false") conditions.MarkFalse(objCopy, clusterv1.ReadyCondition, "reason", clusterv1.ConditionSeverityInfo, "message") - err := v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) g.Expect(env.Status().Update(ctx, objCopy)).To(Succeed()) t.Log("Validating that the local object's resource version is behind") @@ -1706,8 +1677,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Marking Ready clusterv1.condition and metav1.conditions True") conditions.MarkTrue(obj, clusterv1.ReadyCondition) - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj, WithOwnedConditions{Conditions: []clusterv1.ConditionType{clusterv1.ReadyCondition}}, WithOwnedV1Beta2Conditions{Conditions: []string{"Ready"}})).To(Succeed()) @@ -1726,14 +1696,8 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { return false } - readyV1Beta2Before, err := v1beta2conditions.Get(obj, "Ready") - if err != nil { - return false - } - readyV1Beta2After, err := v1beta2conditions.Get(objAfter, "Ready") - if err != nil { - return false - } + readyV1Beta2Before := v1beta2conditions.Get(obj, "Ready") + readyV1Beta2After := v1beta2conditions.Get(objAfter, "Ready") ok, err = v1beta2conditions.MatchCondition(*readyV1Beta2Before).Match(*readyV1Beta2After) if err != nil || !ok { return false @@ -1765,8 +1729,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Marking a Ready clusterv1.condition and metav1.conditions to be false") conditions.MarkFalse(objCopy, clusterv1.ReadyCondition, "reason", clusterv1.ConditionSeverityInfo, "message") - err := v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) g.Expect(env.Status().Update(ctx, objCopy)).To(Succeed()) t.Log("Validating that the local object's resource version is behind") @@ -1778,8 +1741,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Marking Ready clusterv1.condition and metav1.conditions True") conditions.MarkTrue(obj, clusterv1.ReadyCondition) - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj, WithForceOverwriteConditions{})).To(Succeed()) @@ -1798,14 +1760,8 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { return false } - readyV1Beta2Before, err := v1beta2conditions.Get(obj, "Ready") - if err != nil { - return false - } - readyV1Beta2After, err := v1beta2conditions.Get(objAfter, "Ready") - if err != nil { - return false - } + readyV1Beta2Before := v1beta2conditions.Get(obj, "Ready") + readyV1Beta2After := v1beta2conditions.Get(objAfter, "Ready") ok, err = v1beta2conditions.MatchCondition(*readyV1Beta2Before).Match(*readyV1Beta2After) if err != nil || !ok { return false @@ -1849,8 +1805,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Marking condition and back compatibility condition Ready=True") conditions.MarkTrue(obj, clusterv1.ReadyCondition) - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj)).To(Succeed()) @@ -1894,8 +1849,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Marking condition and back compatibility condition Test=False") conditions.MarkFalse(objCopy, clusterv1.ConditionType("Test"), "reason", clusterv1.ConditionSeverityInfo, "message") - err := v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Test", Status: metav1.ConditionFalse, Reason: "reason", Message: "message", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Test", Status: metav1.ConditionFalse, Reason: "reason", Message: "message", LastTransitionTime: now}) g.Expect(env.Status().Update(ctx, objCopy)).To(Succeed()) t.Log("Validating that the local object's resource version is behind") @@ -1907,8 +1861,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Marking condition and back compatibility condition Ready=True") conditions.MarkTrue(obj, clusterv1.ReadyCondition) - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj)).To(Succeed()) @@ -1934,27 +1887,15 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { return false } - testConditionCopy, err := v1beta2conditions.Get(objCopy, "Test") - if err != nil { - return false - } - testConditionAfter, err := v1beta2conditions.Get(objAfter, "Test") - if err != nil { - return false - } + testConditionCopy := v1beta2conditions.Get(objCopy, "Test") + testConditionAfter := v1beta2conditions.Get(objAfter, "Test") ok, err = v1beta2conditions.MatchCondition(*testConditionCopy).Match(*testConditionAfter) if err != nil || !ok { return false } - readyBefore, err := v1beta2conditions.Get(obj, "Ready") - if err != nil { - return false - } - readyAfter, err := v1beta2conditions.Get(objAfter, "Ready") - if err != nil { - return false - } + readyBefore := v1beta2conditions.Get(obj, "Ready") + readyAfter := v1beta2conditions.Get(objAfter, "Ready") ok, err = v1beta2conditions.MatchCondition(*readyBefore).Match(*readyAfter) if err != nil || !ok { return false @@ -1986,8 +1927,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Marking condition and back compatibility condition Test=False") conditions.MarkFalse(objCopy, clusterv1.ConditionType("Test"), "reason", clusterv1.ConditionSeverityInfo, "message") - err := v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Test", Status: metav1.ConditionFalse, Reason: "reason", Message: "message", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Test", Status: metav1.ConditionFalse, Reason: "reason", Message: "message", LastTransitionTime: now}) g.Expect(env.Status().Update(ctx, objCopy)).To(Succeed()) t.Log("Validating that the local object's resource version is behind") @@ -2001,8 +1941,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { obj.Spec.Foo = "foo" obj.Status.Bar = "bat" conditions.MarkTrue(obj, clusterv1.ReadyCondition) - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj)).To(Succeed()) @@ -2029,27 +1968,15 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { return false } - testConditionCopy, err := v1beta2conditions.Get(objCopy, "Test") - if err != nil { - return false - } - testConditionAfter, err := v1beta2conditions.Get(objAfter, "Test") - if err != nil { - return false - } + testConditionCopy := v1beta2conditions.Get(objCopy, "Test") + testConditionAfter := v1beta2conditions.Get(objAfter, "Test") ok, err = v1beta2conditions.MatchCondition(*testConditionCopy).Match(*testConditionAfter) if err != nil || !ok { return false } - readyBefore, err := v1beta2conditions.Get(obj, "Ready") - if err != nil { - return false - } - readyAfter, err := v1beta2conditions.Get(objAfter, "Ready") - if err != nil { - return false - } + readyBefore := v1beta2conditions.Get(obj, "Ready") + readyAfter := v1beta2conditions.Get(objAfter, "Ready") ok, err = v1beta2conditions.MatchCondition(*readyBefore).Match(*readyAfter) if err != nil || !ok { return false @@ -2128,8 +2055,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { objCopy := obj.DeepCopy() t.Log("Marking a Ready condition to be false") - err := v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) g.Expect(env.Status().Update(ctx, objCopy)).To(Succeed()) t.Log("Validating that the local object's resource version is behind") @@ -2140,8 +2066,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) t.Log("Marking condition Ready=True") - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj)).NotTo(Succeed()) @@ -2178,8 +2103,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Marking a Ready condition and back compatibility condition to be false") conditions.MarkFalse(objCopy, clusterv1.ReadyCondition, "reason", clusterv1.ConditionSeverityInfo, "message") - err := v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) g.Expect(env.Status().Update(ctx, objCopy)).To(Succeed()) t.Log("Validating that the local object's resource version is behind") @@ -2191,8 +2115,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Marking Ready condition and back compatibility condition True") conditions.MarkTrue(obj, clusterv1.ReadyCondition) - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj, WithOwnedConditions{Conditions: []clusterv1.ConditionType{clusterv1.ReadyCondition}}, WithOwnedV1Beta2Conditions{Conditions: []string{"Ready"}})).To(Succeed()) @@ -2211,14 +2134,8 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { return false } - readyBefore, err := v1beta2conditions.Get(obj, "Ready") - if err != nil { - return false - } - readyAfter, err := v1beta2conditions.Get(objAfter, "Ready") - if err != nil { - return false - } + readyBefore := v1beta2conditions.Get(obj, "Ready") + readyAfter := v1beta2conditions.Get(objAfter, "Ready") ok, err = v1beta2conditions.MatchCondition(*readyBefore).Match(*readyAfter) if err != nil || !ok { return false @@ -2250,8 +2167,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Marking a Ready condition and back compatibility condition to be false") conditions.MarkFalse(objCopy, clusterv1.ReadyCondition, "reason", clusterv1.ConditionSeverityInfo, "message") - err := v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) g.Expect(env.Status().Update(ctx, objCopy)).To(Succeed()) t.Log("Validating that the local object's resource version is behind") @@ -2263,8 +2179,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Marking Ready condition and back compatibility condition True") conditions.MarkTrue(obj, clusterv1.ReadyCondition) - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj, WithForceOverwriteConditions{})).To(Succeed()) @@ -2283,14 +2198,8 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { return false } - readyBefore, err := v1beta2conditions.Get(obj, "Ready") - if err != nil { - return false - } - readyAfter, err := v1beta2conditions.Get(objAfter, "Ready") - if err != nil { - return false - } + readyBefore := v1beta2conditions.Get(obj, "Ready") + readyAfter := v1beta2conditions.Get(objAfter, "Ready") ok, err = v1beta2conditions.MatchCondition(*readyBefore).Match(*readyAfter) if err != nil || !ok { return false @@ -2333,8 +2242,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) t.Log("Marking condition Ready=True") - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj)).To(Succeed()) @@ -2370,8 +2278,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { objCopy := obj.DeepCopy() t.Log("Marking condition Test=False") - err := v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Test", Status: metav1.ConditionFalse, Reason: "reason", Message: "message", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Test", Status: metav1.ConditionFalse, Reason: "reason", Message: "message", LastTransitionTime: now}) g.Expect(env.Status().Update(ctx, objCopy)).To(Succeed()) t.Log("Validating that the local object's resource version is behind") @@ -2382,8 +2289,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) t.Log("Marking condition Ready=True") - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj)).To(Succeed()) @@ -2395,27 +2301,15 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { return false } - testConditionCopy, err := v1beta2conditions.Get(objCopy, "Test") - if err != nil { - return false - } - testConditionAfter, err := v1beta2conditions.Get(objAfter, "Test") - if err != nil { - return false - } + testConditionCopy := v1beta2conditions.Get(objCopy, "Test") + testConditionAfter := v1beta2conditions.Get(objAfter, "Test") ok, err := v1beta2conditions.MatchCondition(*testConditionCopy).Match(*testConditionAfter) if err != nil || !ok { return false } - readyBefore, err := v1beta2conditions.Get(obj, "Ready") - if err != nil { - return false - } - readyAfter, err := v1beta2conditions.Get(objAfter, "Ready") - if err != nil { - return false - } + readyBefore := v1beta2conditions.Get(obj, "Ready") + readyAfter := v1beta2conditions.Get(objAfter, "Ready") ok, err = v1beta2conditions.MatchCondition(*readyBefore).Match(*readyAfter) if err != nil || !ok { return false @@ -2446,8 +2340,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { objCopy := obj.DeepCopy() t.Log("Marking condition Test=False") - err := v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Test", Status: metav1.ConditionFalse, Reason: "reason", Message: "message", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Test", Status: metav1.ConditionFalse, Reason: "reason", Message: "message", LastTransitionTime: now}) g.Expect(env.Status().Update(ctx, objCopy)).To(Succeed()) t.Log("Validating that the local object's resource version is behind") @@ -2460,8 +2353,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { t.Log("Changing the object spec, status, and marking condition Ready=True") obj.Spec.Foo = "foo" obj.Status.Bar = "bat" - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj)).To(Succeed()) @@ -2474,27 +2366,15 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { return false } - testConditionCopy, err := v1beta2conditions.Get(objCopy, "Test") - if err != nil { - return false - } - testConditionAfter, err := v1beta2conditions.Get(objAfter, "Test") - if err != nil { - return false - } + testConditionCopy := v1beta2conditions.Get(objCopy, "Test") + testConditionAfter := v1beta2conditions.Get(objAfter, "Test") ok, err := v1beta2conditions.MatchCondition(*testConditionCopy).Match(*testConditionAfter) if err != nil || !ok { return false } - readyBefore, err := v1beta2conditions.Get(obj, "Ready") - if err != nil { - return false - } - readyAfter, err := v1beta2conditions.Get(objAfter, "Ready") - if err != nil { - return false - } + readyBefore := v1beta2conditions.Get(obj, "Ready") + readyAfter := v1beta2conditions.Get(objAfter, "Ready") ok, err = v1beta2conditions.MatchCondition(*readyBefore).Match(*readyAfter) if err != nil || !ok { return false @@ -2526,8 +2406,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { objCopy := obj.DeepCopy() t.Log("Marking a Ready condition to be false") - err := v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) g.Expect(env.Status().Update(ctx, objCopy)).To(Succeed()) t.Log("Validating that the local object's resource version is behind") @@ -2538,8 +2417,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) t.Log("Marking condition Ready=True") - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj)).NotTo(Succeed()) @@ -2575,8 +2453,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { objCopy := obj.DeepCopy() t.Log("Marking a Ready condition to be false") - err := v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) g.Expect(env.Status().Update(ctx, objCopy)).To(Succeed()) t.Log("Validating that the local object's resource version is behind") @@ -2587,8 +2464,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) t.Log("Marking Ready condition True") - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj, WithOwnedV1Beta2Conditions{Conditions: []string{"Ready"}})).To(Succeed()) @@ -2600,14 +2476,8 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { return false } - readyBefore, err := v1beta2conditions.Get(obj, "Ready") - if err != nil { - return false - } - readyAfter, err := v1beta2conditions.Get(objAfter, "Ready") - if err != nil { - return false - } + readyBefore := v1beta2conditions.Get(obj, "Ready") + readyAfter := v1beta2conditions.Get(objAfter, "Ready") ok, err := v1beta2conditions.MatchCondition(*readyBefore).Match(*readyAfter) if err != nil || !ok { return false @@ -2638,8 +2508,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { objCopy := obj.DeepCopy() t.Log("Marking a Ready condition to be false") - err := v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(objCopy, metav1.Condition{Type: "Ready", Status: metav1.ConditionFalse, Reason: "NotGood", LastTransitionTime: now}) g.Expect(env.Status().Update(ctx, objCopy)).To(Succeed()) t.Log("Validating that the local object's resource version is behind") @@ -2650,8 +2519,7 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) t.Log("Marking Ready condition True") - err = v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) - g.Expect(err).ToNot(HaveOccurred()) + v1beta2conditions.Set(obj, metav1.Condition{Type: "Ready", Status: metav1.ConditionTrue, Reason: "AllGood", LastTransitionTime: now}) t.Log("Patching the object") g.Expect(patcher.Patch(ctx, obj, WithForceOverwriteConditions{})).To(Succeed()) @@ -2663,14 +2531,8 @@ func TestPatchHelperForV1beta2Transition(t *testing.T) { return false } - readyBefore, err := v1beta2conditions.Get(obj, "Ready") - if err != nil { - return false - } - readyAfter, err := v1beta2conditions.Get(objAfter, "Ready") - if err != nil { - return false - } + readyBefore := v1beta2conditions.Get(obj, "Ready") + readyAfter := v1beta2conditions.Get(objAfter, "Ready") ok, err := v1beta2conditions.MatchCondition(*readyBefore).Match(*readyAfter) if err != nil || !ok { return false diff --git a/util/patch/utils.go b/util/patch/utils.go index b056d4a9d138..d16fa9734841 100644 --- a/util/patch/utils.go +++ b/util/patch/utils.go @@ -71,7 +71,7 @@ func toUnstructured(obj runtime.Object, gvk schema.GroupVersionKind) (*unstructu // It copies the common fields such as `kind`, `apiVersion`, `metadata` and the patchType specified. // // It's not safe to modify any of the keys in the returned unstructured object, the result should be treated as read-only. -func unsafeUnstructuredCopy(obj *unstructured.Unstructured, focus patchType, metav1ConditionsFields, clusterv1ConditionsFields []string) *unstructured.Unstructured { +func unsafeUnstructuredCopy(obj *unstructured.Unstructured, focus patchType, clusterv1ConditionsFieldPath, metav1ConditionsFieldPath []string) *unstructured.Unstructured { // Create the return focused-unstructured object with a preallocated map. res := &unstructured.Unstructured{Object: make(map[string]interface{}, len(obj.Object))} @@ -108,12 +108,11 @@ func unsafeUnstructuredCopy(obj *unstructured.Unstructured, focus patchType, met // copies have a high cpu and high memory usage, therefore we intentionally choose to avoid extra copies // given that the ordering of operations and safety is handled internally by the patch helper. if focus == statusPatch { - if len(metav1ConditionsFields) > 0 { - unstructured.RemoveNestedField(res.Object, metav1ConditionsFields...) + if len(clusterv1ConditionsFieldPath) > 0 { + unstructured.RemoveNestedField(res.Object, clusterv1ConditionsFieldPath...) } - - if len(clusterv1ConditionsFields) > 0 { - unstructured.RemoveNestedField(res.Object, clusterv1ConditionsFields...) + if len(metav1ConditionsFieldPath) > 0 { + unstructured.RemoveNestedField(res.Object, metav1ConditionsFieldPath...) } } @@ -125,7 +124,7 @@ var ( metav1ConditionsType = reflect.TypeOf([]metav1.Condition{}) ) -func identifySupportedConditions(obj runtime.Object) ([]string, []string, error) { +func identifyConditionsFieldsPath(obj runtime.Object) ([]string, []string, error) { if obj == nil { return nil, nil, errors.New("cannot identify conditions on a nil object") } diff --git a/util/patch/utils_test.go b/util/patch/utils_test.go index c89a6e640046..76858c852a49 100644 --- a/util/patch/utils_test.go +++ b/util/patch/utils_test.go @@ -244,12 +244,12 @@ func TestUnsafeFocusedUnstructured(t *testing.T) { }) } -func TestIdentifySupportedConditions(t *testing.T) { +func TestIdentifyConditionsFieldsPath(t *testing.T) { t.Run("v1beta1 object with conditions (phase 0)", func(t *testing.T) { g := NewWithT(t) obj := &builder.Phase0Obj{} - metav1ConditionsFields, clusterv1ConditionsFields, err := identifySupportedConditions(obj) + metav1ConditionsFields, clusterv1ConditionsFields, err := identifyConditionsFieldsPath(obj) g.Expect(err).ToNot(HaveOccurred()) g.Expect(metav1ConditionsFields).To(BeEmpty()) g.Expect(clusterv1ConditionsFields).To(Equal([]string{"status", "conditions"})) @@ -265,7 +265,7 @@ func TestIdentifySupportedConditions(t *testing.T) { {obj: &builder.Phase1Obj{Status: builder.Phase1ObjStatus{V1Beta2: &builder.Phase1ObjStatusV1Beta2{Conditions: nil}}}}, } for _, tt := range tests { - metav1ConditionsFields, clusterv1ConditionsFields, err := identifySupportedConditions(tt.obj) + metav1ConditionsFields, clusterv1ConditionsFields, err := identifyConditionsFieldsPath(tt.obj) g.Expect(err).ToNot(HaveOccurred()) g.Expect(metav1ConditionsFields).To(Equal([]string{"status", "v1beta2", "conditions"})) g.Expect(clusterv1ConditionsFields).To(Equal([]string{"status", "conditions"})) @@ -283,7 +283,7 @@ func TestIdentifySupportedConditions(t *testing.T) { {obj: &builder.Phase2Obj{Status: builder.Phase2ObjStatus{Deprecated: &builder.Phase2ObjStatusDeprecated{V1Beta1: &builder.Phase2ObjStatusDeprecatedV1Beta1{Conditions: nil}}}}}, } for _, tt := range tests { - metav1ConditionsFields, clusterv1ConditionsFields, err := identifySupportedConditions(tt.obj) + metav1ConditionsFields, clusterv1ConditionsFields, err := identifyConditionsFieldsPath(tt.obj) g.Expect(err).ToNot(HaveOccurred()) g.Expect(metav1ConditionsFields).To(Equal([]string{"status", "conditions"})) g.Expect(clusterv1ConditionsFields).To(Equal([]string{"status", "deprecated", "v1beta1", "conditions"})) @@ -293,7 +293,7 @@ func TestIdentifySupportedConditions(t *testing.T) { g := NewWithT(t) obj := &builder.Phase3Obj{} - metav1ConditionsFields, clusterv1ConditionsFields, err := identifySupportedConditions(obj) + metav1ConditionsFields, clusterv1ConditionsFields, err := identifyConditionsFieldsPath(obj) g.Expect(err).ToNot(HaveOccurred()) g.Expect(metav1ConditionsFields).To(Equal([]string{"status", "conditions"})) g.Expect(clusterv1ConditionsFields).To(BeEmpty())