...

Source file src/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfieldsupdater.go

Documentation: k8s.io/apimachinery/pkg/util/managedfields/internal

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package internal
    18  
    19  import (
    20  	"time"
    21  
    22  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    23  	"k8s.io/apimachinery/pkg/runtime"
    24  	"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
    25  )
    26  
    27  type managedFieldsUpdater struct {
    28  	fieldManager Manager
    29  }
    30  
    31  var _ Manager = &managedFieldsUpdater{}
    32  
    33  // NewManagedFieldsUpdater is responsible for updating the managedfields
    34  // in the object, updating the time of the operation as necessary. For
    35  // updates, it uses a hard-coded manager to detect if things have
    36  // changed, and swaps back the correct manager after the operation is
    37  // done.
    38  func NewManagedFieldsUpdater(fieldManager Manager) Manager {
    39  	return &managedFieldsUpdater{
    40  		fieldManager: fieldManager,
    41  	}
    42  }
    43  
    44  // Update implements Manager.
    45  func (f *managedFieldsUpdater) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) {
    46  	self := "current-operation"
    47  	object, managed, err := f.fieldManager.Update(liveObj, newObj, managed, self)
    48  	if err != nil {
    49  		return object, managed, err
    50  	}
    51  
    52  	// If the current operation took any fields from anything, it means the object changed,
    53  	// so update the timestamp of the managedFieldsEntry and merge with any previous updates from the same manager
    54  	if vs, ok := managed.Fields()[self]; ok {
    55  		delete(managed.Fields(), self)
    56  
    57  		if previous, ok := managed.Fields()[manager]; ok {
    58  			managed.Fields()[manager] = fieldpath.NewVersionedSet(vs.Set().Union(previous.Set()), vs.APIVersion(), vs.Applied())
    59  		} else {
    60  			managed.Fields()[manager] = vs
    61  		}
    62  
    63  		managed.Times()[manager] = &metav1.Time{Time: time.Now().UTC()}
    64  	}
    65  
    66  	return object, managed, nil
    67  }
    68  
    69  // Apply implements Manager.
    70  func (f *managedFieldsUpdater) Apply(liveObj, appliedObj runtime.Object, managed Managed, fieldManager string, force bool) (runtime.Object, Managed, error) {
    71  	object, managed, err := f.fieldManager.Apply(liveObj, appliedObj, managed, fieldManager, force)
    72  	if err != nil {
    73  		return object, managed, err
    74  	}
    75  	if object != nil {
    76  		managed.Times()[fieldManager] = &metav1.Time{Time: time.Now().UTC()}
    77  	} else {
    78  		object = liveObj.DeepCopyObject()
    79  		RemoveObjectManagedFields(object)
    80  	}
    81  	return object, managed, nil
    82  }
    83  

View as plain text