sigs.k8s.io/cluster-api@v1.7.1/internal/controllers/topology/cluster/structuredmerge/drop_diff.go (about)

     1  /*
     2  Copyright 2022 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 structuredmerge
    18  
    19  import "sigs.k8s.io/cluster-api/internal/contract"
    20  
    21  // dropDiff allow to change the modified object so the generated patch will not contain changes
    22  // that match the shouldDropDiff criteria.
    23  // NOTE: This func is called recursively only for fields of type Map, but this is ok given the current use cases
    24  // this func has to address. More specifically, we are using only for not allowed paths and for ignore paths;
    25  // all of them are defined in reconcile_state.go and are targeting well-known fields inside nested maps.
    26  // Allowed paths / ignore paths which point to an array are not supported by the current implementation.
    27  func dropDiff(ctx *dropDiffInput) {
    28  	original, _ := ctx.original.(map[string]interface{})
    29  	modified, _ := ctx.modified.(map[string]interface{})
    30  	for field := range modified {
    31  		fieldCtx := &dropDiffInput{
    32  			// Compose the path for the nested field.
    33  			path: ctx.path.Append(field),
    34  			// Gets the original and the modified value for the field.
    35  			original: original[field],
    36  			modified: modified[field],
    37  			// Carry over global values from the context.
    38  			shouldDropDiffFunc: ctx.shouldDropDiffFunc,
    39  		}
    40  
    41  		// Note: for everything we should drop changes we are making modified equal to original, so the generated patch doesn't include this change
    42  		if fieldCtx.shouldDropDiffFunc(fieldCtx.path) {
    43  			// If original exists, make modified equal to original, otherwise if original does not exist, drop the change.
    44  			if o, ok := original[field]; ok {
    45  				modified[field] = o
    46  			} else {
    47  				delete(modified, field)
    48  			}
    49  			continue
    50  		}
    51  
    52  		// Process nested fields.
    53  		dropDiff(fieldCtx)
    54  
    55  		// Ensure we are not leaving empty maps around.
    56  		if v, ok := fieldCtx.modified.(map[string]interface{}); ok && len(v) == 0 {
    57  			delete(modified, field)
    58  		}
    59  	}
    60  }
    61  
    62  // dropDiffInput holds info required while computing dropDiff.
    63  type dropDiffInput struct {
    64  	// the path of the field being processed.
    65  	path contract.Path
    66  
    67  	// the original and the modified value for the current path.
    68  	original interface{}
    69  	modified interface{}
    70  
    71  	// shouldDropDiffFunc handle the func that determine if the current path should be dropped or not.
    72  	shouldDropDiffFunc func(path contract.Path) bool
    73  }