// reorganizeTaints returns the updated set of taints, taking into account old taints that were not updated, // old taints that were updated, old taints that were deleted, and new taints. func reorganizeTaints(accessor metav1.Object, overwrite bool, taintsToAdd []v1.Taint, taintsToRemove []v1.Taint) ([]v1.Taint, error) { newTaints := append([]v1.Taint{}, taintsToAdd...) var oldTaints []v1.Taint var err error annotations := accessor.GetAnnotations() if annotations != nil { if oldTaints, err = v1.GetTaintsFromNodeAnnotations(annotations); err != nil { return nil, err } } // add taints that already existing but not updated to newTaints for _, oldTaint := range oldTaints { existsInNew := false for _, taint := range newTaints { if taint.MatchTaint(oldTaint) { existsInNew = true break } } if !existsInNew { newTaints = append(newTaints, oldTaint) } } allErrs := []error{} for _, taintToRemove := range taintsToRemove { newTaints, err = deleteTaint(newTaints, taintToRemove) if err != nil { allErrs = append(allErrs, err) } } return newTaints, utilerrors.NewAggregate(allErrs) }
func validateNoOverwrites(accessor metav1.Object, labels map[string]string) error { allErrs := []error{} for key := range labels { if value, found := accessor.GetLabels()[key]; found { allErrs = append(allErrs, fmt.Errorf("'%s' already has a value (%s), and --overwrite is false", key, value)) } } return utilerrors.NewAggregate(allErrs) }
// validateNoAnnotationOverwrites validates that when overwrite is false, to-be-updated annotations don't exist in the object annotation map (yet) func validateNoAnnotationOverwrites(accessor metav1.Object, annotations map[string]string) error { var buf bytes.Buffer for key := range annotations { // change-cause annotation can always be overwritten if key == kubectl.ChangeCauseAnnotation { continue } if value, found := accessor.GetAnnotations()[key]; found { if buf.Len() > 0 { buf.WriteString("; ") } buf.WriteString(fmt.Sprintf("'%s' already has a value (%s)", key, value)) } } if buf.Len() > 0 { return fmt.Errorf("--overwrite is false but found the following declared annotation(s): %s", buf.String()) } return nil }
func shouldOrphanDependents(e *event, accessor metav1.Object) bool { // The delta_fifo may combine the creation and update of the object into one // event, so we need to check AddEvent as well. if e.oldObj == nil { if accessor.GetDeletionTimestamp() == nil { return false } } else { oldAccessor, err := meta.Accessor(e.oldObj) if err != nil { utilruntime.HandleError(fmt.Errorf("cannot access oldObj: %v", err)) return false } // ignore the event if it's not updating DeletionTimestamp from non-nil to nil. if accessor.GetDeletionTimestamp() == nil || oldAccessor.GetDeletionTimestamp() != nil { return false } } finalizers := accessor.GetFinalizers() for _, finalizer := range finalizers { if finalizer == v1.FinalizerOrphan { return true } } return false }
// shouldUpdateFinalizers returns if we need to update the finalizers of the // object, and the desired list of finalizers. // When deciding whether to add the OrphanDependent finalizer, factors in the // order of highest to lowest priority are: options.OrphanDependents, existing // finalizers of the object, e.DeleteStrategy.DefaultGarbageCollectionPolicy. func shouldUpdateFinalizers(e *Store, accessor metav1.Object, options *api.DeleteOptions) (shouldUpdate bool, newFinalizers []string) { shouldOrphan := false // Get default orphan policy from this REST object type if gcStrategy, ok := e.DeleteStrategy.(rest.GarbageCollectionDeleteStrategy); ok { if gcStrategy.DefaultGarbageCollectionPolicy() == rest.OrphanDependents { shouldOrphan = true } } // If a finalizer is set in the object, it overrides the default hasOrphanFinalizer := false finalizers := accessor.GetFinalizers() for _, f := range finalizers { if f == api.FinalizerOrphan { shouldOrphan = true hasOrphanFinalizer = true break } // TODO: update this when we add a finalizer indicating a preference for the other behavior } // If an explicit policy was set at deletion time, that overrides both if options != nil && options.OrphanDependents != nil { shouldOrphan = *options.OrphanDependents } if shouldOrphan && !hasOrphanFinalizer { finalizers = append(finalizers, api.FinalizerOrphan) return true, finalizers } if !shouldOrphan && hasOrphanFinalizer { var newFinalizers []string for _, f := range finalizers { if f == api.FinalizerOrphan { continue } newFinalizers = append(newFinalizers, f) } return true, newFinalizers } return false, finalizers }
// validateNoTaintOverwrites validates that when overwrite is false, to-be-updated taints don't exist in the node taint list (yet) func validateNoTaintOverwrites(accessor metav1.Object, taints []v1.Taint) error { annotations := accessor.GetAnnotations() if annotations == nil { return nil } allErrs := []error{} oldTaints, err := v1.GetTaintsFromNodeAnnotations(annotations) if err != nil { allErrs = append(allErrs, err) return utilerrors.NewAggregate(allErrs) } for _, taint := range taints { for _, oldTaint := range oldTaints { if taint.Key == oldTaint.Key && taint.Effect == oldTaint.Effect { allErrs = append(allErrs, fmt.Errorf("Node '%s' already has a taint with key (%s) and effect (%v), and --overwrite is false", accessor.GetName(), taint.Key, taint.Effect)) break } } } return utilerrors.NewAggregate(allErrs) }
func (f *FakeControllerSource) key(accessor metav1.Object) nnu { return nnu{accessor.GetNamespace(), accessor.GetName(), accessor.GetUID()} }
func exportObjectMeta(accessor metav1.Object, exact bool) { accessor.SetUID("") if !exact { accessor.SetNamespace("") } accessor.SetCreationTimestamp(metav1.Time{}) accessor.SetDeletionTimestamp(nil) accessor.SetResourceVersion("") accessor.SetSelfLink("") if len(accessor.GetGenerateName()) > 0 && !exact { accessor.SetName("") } }