// FillObjectMetaSystemFields populates fields that are managed by the system on ObjectMeta. func FillObjectMetaSystemFields(ctx genericapirequest.Context, meta *metav1.ObjectMeta) { meta.CreationTimestamp = metav1.Now() // allows admission controllers to assign a UID earlier in the request processing // to support tracking resources pending creation. uid, found := genericapirequest.UIDFrom(ctx) if !found { uid = uuid.NewUUID() } meta.UID = uid meta.SelfLink = "" }
// ValidNamespace returns false if the namespace on the context differs from the resource. If the resource has no namespace, it is set to the value in the context. // TODO(sttts): move into pkg/genericapiserver/endpoints func ValidNamespace(ctx genericapirequest.Context, resource *metav1.ObjectMeta) bool { ns, ok := genericapirequest.NamespaceFrom(ctx) if len(resource.Namespace) == 0 { resource.Namespace = ns } return ns == resource.Namespace && ok }
func SetMasterTaintTolerations(meta *metav1.ObjectMeta) { tolerationsAnnotation, _ := json.Marshal([]v1.Toleration{{Key: "dedicated", Value: "master", Effect: "NoSchedule"}}) if meta.Annotations == nil { meta.Annotations = map[string]string{} } meta.Annotations[v1.TolerationsAnnotationKey] = string(tolerationsAnnotation) }
// SetNodeAffinity is a basic helper to set meta.Annotations[v1.AffinityAnnotationKey] for one or more v1.NodeSelectorRequirement(s) func SetNodeAffinity(meta *metav1.ObjectMeta, expr ...v1.NodeSelectorRequirement) { nodeAffinity := &v1.NodeAffinity{ RequiredDuringSchedulingIgnoredDuringExecution: &v1.NodeSelector{ NodeSelectorTerms: []v1.NodeSelectorTerm{{MatchExpressions: expr}}, }, } affinityAnnotation, _ := json.Marshal(v1.Affinity{NodeAffinity: nodeAffinity}) if meta.Annotations == nil { meta.Annotations = map[string]string{} } meta.Annotations[v1.AffinityAnnotationKey] = string(affinityAnnotation) }
// ValidateObjectMetaUpdate validates an object's metadata when updated func ValidateObjectMetaUpdate(newMeta, oldMeta *metav1.ObjectMeta, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if !RepairMalformedUpdates && newMeta.UID != oldMeta.UID { allErrs = append(allErrs, field.Invalid(fldPath.Child("uid"), newMeta.UID, "field is immutable")) } // in the event it is left empty, set it, to allow clients more flexibility // TODO: remove the following code that repairs the update request when we retire the clients that modify the immutable fields. // Please do not copy this pattern elsewhere; validation functions should not be modifying the objects they are passed! if RepairMalformedUpdates { if len(newMeta.UID) == 0 { newMeta.UID = oldMeta.UID } // ignore changes to timestamp if oldMeta.CreationTimestamp.IsZero() { oldMeta.CreationTimestamp = newMeta.CreationTimestamp } else { newMeta.CreationTimestamp = oldMeta.CreationTimestamp } // an object can never remove a deletion timestamp or clear/change grace period seconds if !oldMeta.DeletionTimestamp.IsZero() { newMeta.DeletionTimestamp = oldMeta.DeletionTimestamp } if oldMeta.DeletionGracePeriodSeconds != nil && newMeta.DeletionGracePeriodSeconds == nil { newMeta.DeletionGracePeriodSeconds = oldMeta.DeletionGracePeriodSeconds } } // TODO: needs to check if newMeta==nil && oldMeta !=nil after the repair logic is removed. if newMeta.DeletionGracePeriodSeconds != nil && (oldMeta.DeletionGracePeriodSeconds == nil || *newMeta.DeletionGracePeriodSeconds != *oldMeta.DeletionGracePeriodSeconds) { allErrs = append(allErrs, field.Invalid(fldPath.Child("deletionGracePeriodSeconds"), newMeta.DeletionGracePeriodSeconds, "field is immutable; may only be changed via deletion")) } if newMeta.DeletionTimestamp != nil && (oldMeta.DeletionTimestamp == nil || !newMeta.DeletionTimestamp.Equal(*oldMeta.DeletionTimestamp)) { allErrs = append(allErrs, field.Invalid(fldPath.Child("deletionTimestamp"), newMeta.DeletionTimestamp, "field is immutable; may only be changed via deletion")) } // Finalizers cannot be added if the object is already being deleted. if oldMeta.DeletionTimestamp != nil { allErrs = append(allErrs, ValidateNoNewFinalizers(newMeta.Finalizers, oldMeta.Finalizers, fldPath.Child("finalizers"))...) } // Reject updates that don't specify a resource version if len(newMeta.ResourceVersion) == 0 { allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceVersion"), newMeta.ResourceVersion, "must be specified for an update")) } // Generation shouldn't be decremented if newMeta.Generation < oldMeta.Generation { allErrs = append(allErrs, field.Invalid(fldPath.Child("generation"), newMeta.Generation, "must not be decremented")) } allErrs = append(allErrs, ValidateImmutableField(newMeta.Name, oldMeta.Name, fldPath.Child("name"))...) allErrs = append(allErrs, ValidateImmutableField(newMeta.Namespace, oldMeta.Namespace, fldPath.Child("namespace"))...) allErrs = append(allErrs, ValidateImmutableField(newMeta.UID, oldMeta.UID, fldPath.Child("uid"))...) allErrs = append(allErrs, ValidateImmutableField(newMeta.CreationTimestamp, oldMeta.CreationTimestamp, fldPath.Child("creationTimestamp"))...) allErrs = append(allErrs, ValidateImmutableField(newMeta.ClusterName, oldMeta.ClusterName, fldPath.Child("clusterName"))...) allErrs = append(allErrs, v1validation.ValidateLabels(newMeta.Labels, fldPath.Child("labels"))...) allErrs = append(allErrs, ValidateAnnotations(newMeta.Annotations, fldPath.Child("annotations"))...) allErrs = append(allErrs, ValidateOwnerReferences(newMeta.OwnerReferences, fldPath.Child("ownerReferences"))...) return allErrs }