// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
322495
func (strategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
	newCRD := obj.(*apiextensions.CustomResourceDefinition)
	oldCRD := old.(*apiextensions.CustomResourceDefinition)
	newCRD.Status = oldCRD.Status

	// Any changes to the spec increment the generation number, any changes to the
	// status should reflect the generation number of the corresponding object. We push
	// the burden of managing the status onto the clients because we can't (in general)
	// know here what version of spec the writer of the status has seen. It may seem like
	// we can at first -- since obj contains spec -- but in the future we will probably make
	// status its own object, and even if we don't, writes may be the result of a
	// read-update-write loop, so the contents of spec may not actually be the spec that
	// the controller has *seen*.
	if !apiequality.Semantic.DeepEqual(oldCRD.Spec, newCRD.Spec) {
		newCRD.Generation = oldCRD.Generation + 1
	}

	dropDisabledFields(&newCRD.Spec, &oldCRD.Spec)

	for _, v := range newCRD.Spec.Versions {
		if v.Storage {
			if !apiextensions.IsStoredVersion(newCRD, v.Name) {
				newCRD.Status.StoredVersions = append(newCRD.Status.StoredVersions, v.Name)
			}
			break
		}
	}
}
832748
func (s imageStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
	newImage := obj.(*imageapi.Image)
	// ignore errors, change in place
	if err := util.InternalImageWithMetadata(newImage); err != nil {
		utilruntime.HandleError(fmt.Errorf("Unable to update image metadata for %q: %v", newImage.Name, err))
	}
	if newImage.Annotations[imageapi.ImageManifestBlobStoredAnnotation] == "true" {
		newImage.DockerImageManifest = ""
		newImage.DockerImageConfig = ""
	}

	removeManagedSignatureAnnotation(newImage)
}
1279173
func (strategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
	_ = obj.(*node.RuntimeClass)
}
754491
func (l *lbmapCache) prepareUpdate(fe ServiceKey, backends []ServiceValue) (
	*bpfService, map[loadbalancer.BackendID]ServiceValue, []loadbalancer.BackendID, error) {

	l.mutex.Lock()
	defer l.mutex.Unlock()

	frontendID := fe.String()

	bpfSvc, ok := l.entries[frontendID]
	if !ok {
		bpfSvc = newBpfService(fe)
		l.entries[frontendID] = bpfSvc
	}

	newBackendsMap := createBackendsMap(backends)
	toRemoveBackendIDs := []loadbalancer.BackendID{}
	toAddBackendIDs := map[loadbalancer.BackendID]ServiceValue{}

	// Step 1: Delete all backends that no longer exist. This will not
	// actually remove the backends but overwrite all slave slots that
	// point to the removed backend with the backend that has the least
	// duplicated slots.
	if option.Config.EnableLegacyServices {
		for addrID, b := range bpfSvc.uniqueBackends {
			if _, ok := newBackendsMap[addrID]; !ok {
				bpfSvc.deleteBackend(b)
				delete(bpfSvc.slaveSlotByBackendAddrID, addrID)
			}
		}
	}
	// Step 2: Delete all backends that no longer exist in the service v2.
	for addrID := range bpfSvc.backendsV2 {
		if _, ok := newBackendsMap[addrID]; !ok {
			isLastInstanceRemoved, err := l.delBackendV2Locked(addrID)
			if err != nil {
				return nil, nil, nil, err
			}
			if isLastInstanceRemoved {
				toRemoveBackendIDs = append(toRemoveBackendIDs,
					l.backendIDByAddrID[addrID])
				delete(l.backendIDByAddrID, addrID)
			}
			delete(bpfSvc.backendsV2, addrID)
		}
	}

	if option.Config.EnableLegacyServices {
		// Step 3: Add all backends that don't exist in the legacy service yet.
		for _, b := range backends {
			if _, ok := bpfSvc.uniqueBackends[b.BackendAddrID()]; !ok {
				addrID := b.BackendAddrID()
				pos := bpfSvc.addBackend(b)
				bpfSvc.slaveSlotByBackendAddrID[addrID] = pos
			}
		}
	}
	// Step 4: Add all backends that don't exist in the service v2 yet.
	for _, b := range backends {
		addrID := b.BackendAddrID()
		if _, ok := bpfSvc.backendsV2[addrID]; !ok {
			bpfSvc.backendsV2[addrID] = b
			isNew := l.addBackendV2Locked(addrID)
			if isNew {
				toAddBackendIDs[l.backendIDByAddrID[addrID]] = b
			}
		}
	}

	return bpfSvc, toAddBackendIDs, toRemoveBackendIDs, nil
}
189095
func (cronJobStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
	cronJob := obj.(*batch.CronJob)
	cronJob.Status = batch.CronJobStatus{}

	pod.DropDisabledTemplateFields(&cronJob.Spec.JobTemplate.Spec.Template, nil)
}
1346340
func (rcStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
	newController := obj.(*api.ReplicationController)
	oldController := old.(*api.ReplicationController)
	// update is not allowed to set status
	newController.Status = oldController.Status

	pod.DropDisabledTemplateFields(newController.Spec.Template, oldController.Spec.Template)

	// Any changes to the spec increment the generation number, any changes to the
	// status should reflect the generation number of the corresponding object. We push
	// the burden of managing the status onto the clients because we can't (in general)
	// know here what version of spec the writer of the status has seen. It may seem like
	// we can at first -- since obj contains spec -- but in the future we will probably make
	// status its own object, and even if we don't, writes may be the result of a
	// read-update-write loop, so the contents of spec may not actually be the spec that
	// the controller has *seen*.
	if !apiequality.Semantic.DeepEqual(oldController.Spec, newController.Spec) {
		newController.Generation = oldController.Generation + 1
	}
}
705481
func (detailsStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
	newBuild := obj.(*buildapi.Build)
	oldBuild := old.(*buildapi.Build)

	// ignore phase updates unless the caller is updating the build to
	// a completed phase.
	phase := oldBuild.Status.Phase
	stages := newBuild.Status.Stages
	if buildinternalhelpers.IsBuildComplete(newBuild) {
		phase = newBuild.Status.Phase
	}
	revision := newBuild.Spec.Revision
	message := newBuild.Status.Message
	reason := newBuild.Status.Reason
	outputTo := newBuild.Status.Output.To
	*newBuild = *oldBuild
	newBuild.Status.Phase = phase
	newBuild.Status.Stages = stages
	newBuild.Spec.Revision = revision
	newBuild.Status.Reason = reason
	newBuild.Status.Message = message
	newBuild.Status.Output.To = outputTo
}
312639
func (u *Updater) checkForUpdate(ctx Context, options UpdateOptions) (*Update, error) {
	u.log.Infof("Checking for update, current version is %s", options.Version)
	u.log.Infof("Using updater source: %s", u.source.Description())
	u.log.Debugf("Using options: %#v", options)

	update, findErr := u.source.FindUpdate(options)
	if findErr != nil {
		return nil, findErr
	}
	if update == nil {
		return nil, nil
	}

	// Save InstallID if we received one
	if update.InstallID != "" && u.config.GetInstallID() != update.InstallID {
		u.log.Debugf("Saving install ID: %s", update.InstallID)
		if err := u.config.SetInstallID(update.InstallID); err != nil {
			u.log.Warningf("Error saving install ID: %s", err)
			ctx.ReportError(configErr(fmt.Errorf("Error saving install ID: %s", err)), update, options)
		}
	}

	return update, nil
}
809007
func (autoscalerStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
	newHPA := obj.(*autoscaling.HorizontalPodAutoscaler)

	// create cannot set status
	newHPA.Status = autoscaling.HorizontalPodAutoscalerStatus{}
}
547305
func (s userIdentityMappingStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
	mapping := obj.(*userapi.UserIdentityMapping)

	if len(mapping.Name) == 0 {
		mapping.Name = mapping.Identity.Name
	}
	mapping.Namespace = ""

	mapping.Identity.Namespace = ""
	mapping.Identity.Kind = ""
	mapping.Identity.UID = ""

	mapping.User.Namespace = ""
	mapping.User.Kind = ""
	mapping.User.UID = ""
}
191208
func (auditSinkStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
	newIC := obj.(*audit.AuditSink)
	oldIC := old.(*audit.AuditSink)

	// Any changes to the policy or backend increment the generation number
	// See metav1.ObjectMeta description for more information on Generation.
	if !reflect.DeepEqual(oldIC.Spec, newIC.Spec) {
		newIC.Generation = oldIC.Generation + 1
	}
}
1088910
func (persistentvolumeStatusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
	newPv := obj.(*api.PersistentVolume)
	oldPv := old.(*api.PersistentVolume)
	newPv.Spec = oldPv.Spec
}
1204748
func (resourcequotaStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
	newResourcequota := obj.(*api.ResourceQuota)
	oldResourcequota := old.(*api.ResourceQuota)
	newResourcequota.Status = oldResourcequota.Status
	resourcequotautil.DropDisabledFields(&newResourcequota.Spec, &oldResourcequota.Spec)
}
195870
func (podDisruptionBudgetStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
	podDisruptionBudget := obj.(*policy.PodDisruptionBudget)
	// create cannot set status
	podDisruptionBudget.Status = policy.PodDisruptionBudgetStatus{}

	podDisruptionBudget.Generation = 1
}
1102169
func (csrApprovalStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
	newCSR := obj.(*certificates.CertificateSigningRequest)
	oldCSR := old.(*certificates.CertificateSigningRequest)

	// Updating the approval should only update the conditions.
	newCSR.Spec = oldCSR.Spec
	oldCSR.Status.Conditions = newCSR.Status.Conditions
	for i := range newCSR.Status.Conditions {
		// The Conditions are an array of values, some of which may be
		// pre-existing and unaltered by this update, so a LastUpdateTime is
		// added only if one isn't already set.
		if newCSR.Status.Conditions[i].LastUpdateTime.IsZero() {
			newCSR.Status.Conditions[i].LastUpdateTime = metav1.Now()
		}
	}
	newCSR.Status = oldCSR.Status
}
424869
func (volumeAttachmentStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
	var groupVersion schema.GroupVersion

	if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found {
		groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion}
	}

	switch groupVersion {
	case storageapiv1beta1.SchemeGroupVersion:
		// allow modification of status for v1beta1
	default:
		volumeAttachment := obj.(*storage.VolumeAttachment)
		volumeAttachment.Status = storage.VolumeAttachmentStatus{}
	}
}
1370425
func (a customResourceStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
	newCustomResourceObject := obj.(*unstructured.Unstructured)
	oldCustomResourceObject := old.(*unstructured.Unstructured)

	newCustomResource := newCustomResourceObject.UnstructuredContent()
	oldCustomResource := oldCustomResourceObject.UnstructuredContent()

	// If the /status subresource endpoint is installed, update is not allowed to set status.
	if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && a.status != nil {
		_, ok1 := newCustomResource["status"]
		_, ok2 := oldCustomResource["status"]
		switch {
		case ok2:
			newCustomResource["status"] = oldCustomResource["status"]
		case ok1:
			delete(newCustomResource, "status")
		}
	}

	// except for the changes to `metadata`, any other changes
	// cause the generation to increment.
	newCopyContent := copyNonMetadata(newCustomResource)
	oldCopyContent := copyNonMetadata(oldCustomResource)
	if !apiequality.Semantic.DeepEqual(newCopyContent, oldCopyContent) {
		oldAccessor, _ := meta.Accessor(oldCustomResourceObject)
		newAccessor, _ := meta.Accessor(newCustomResourceObject)
		newAccessor.SetGeneration(oldAccessor.GetGeneration() + 1)
	}
}