Exemple #1
0
// 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 meta.Object, overwrite bool, taintsToAdd []api.Taint, taintsToRemove []api.Taint) ([]api.Taint, error) {
	newTaints := append([]api.Taint{}, taintsToAdd...)

	var oldTaints []api.Taint
	var err error
	annotations := accessor.GetAnnotations()
	if annotations != nil {
		if oldTaints, err = api.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)
}
Exemple #2
0
func validateNoOverwrites(accessor meta.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)
}
Exemple #3
0
// patchObj patches calculates a patch between the given new object and the existing marshaled object
func patchObj(obj runtime.Object, metadata meta.Object, oldData []byte, mapping *meta.RESTMapping, f *clientcmd.Factory) (runtime.Object, error) {
	newData, err := json.Marshal(obj)
	if err != nil {
		return nil, err
	}

	patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, obj)
	if err != nil {
		return nil, err
	}

	client, err := f.ClientForMapping(mapping)
	if err != nil {
		return nil, err
	}
	helper := resource.NewHelper(client, mapping)

	return helper.Patch(metadata.GetNamespace(), metadata.GetName(), kapi.StrategicMergePatchType, patchBytes)
}
Exemple #4
0
// validateNoAnnotationOverwrites validates that when overwrite is false, to-be-updated annotations don't exist in the object annotation map (yet)
func validateNoAnnotationOverwrites(accessor meta.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 meta.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 == api.FinalizerOrphan {
			return true
		}
	}
	return false
}
Exemple #6
0
// 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 meta.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
}
Exemple #7
0
// return if we need to update the finalizers of the object, and the desired list of finalizers
func shouldUpdateFinalizers(accessor meta.Object, options *api.DeleteOptions) (shouldUpdate bool, newFinalizers []string) {
	if options == nil || options.OrphanDependents == nil {
		return false, accessor.GetFinalizers()
	}
	shouldOrphan := *options.OrphanDependents
	alreadyOrphan := false
	finalizers := accessor.GetFinalizers()
	newFinalizers = make([]string, 0, len(finalizers))
	for _, f := range finalizers {
		if f == api.FinalizerOrphan {
			alreadyOrphan = true
			if !shouldOrphan {
				continue
			}
		}
		newFinalizers = append(newFinalizers, f)
	}
	if shouldOrphan && !alreadyOrphan {
		newFinalizers = append(newFinalizers, api.FinalizerOrphan)
	}
	shouldUpdate = shouldOrphan != alreadyOrphan
	return shouldUpdate, newFinalizers
}
Exemple #8
0
// validateNoTaintOverwrites validates that when overwrite is false, to-be-updated taints don't exist in the node taint list (yet)
func validateNoTaintOverwrites(accessor meta.Object, taints []api.Taint) error {
	annotations := accessor.GetAnnotations()
	if annotations == nil {
		return nil
	}

	allErrs := []error{}
	oldTaints, err := api.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)
}
Exemple #9
0
func exportObjectMeta(accessor meta.Object, exact bool) {
	accessor.SetUID("")
	if !exact {
		accessor.SetNamespace("")
	}
	accessor.SetCreationTimestamp(unversioned.Time{})
	accessor.SetDeletionTimestamp(nil)
	accessor.SetResourceVersion("")
	accessor.SetSelfLink("")
	if len(accessor.GetGenerateName()) > 0 && !exact {
		accessor.SetName("")
	}
}
func (f *FakeControllerSource) key(accessor meta.Object) nnu {
	return nnu{accessor.GetNamespace(), accessor.GetName(), accessor.GetUID()}
}