Adjust the validation to the current state

This commit is contained in:
Michal Wozniak
2024-03-07 22:59:14 +01:00
parent 1163c7ed9c
commit 79fe37537c
10 changed files with 12 additions and 53 deletions

View File

@@ -4821,7 +4821,7 @@
"description": "Represents time when the job was completed. It is not guaranteed to be set in happens-before order across separate operations. It is represented in RFC3339 form and is in UTC. The completion time is set when the job finishes successfully, and only then. The value cannot be updated or removed. The value indicates the same or later point in time as the startTime field."
},
"conditions": {
"description": "The latest available observations of an object's current state. When a Job fails, one of the conditions will have type \"Failed\" and status true. When a Job is suspended, one of the conditions will have type \"Suspended\" and status true; when the Job is resumed, the status of this condition will become false. When a Job is completed, one of the conditions will have type \"Complete\" and status true.\n\nA job is considered finished when it is in a terminal condition, either \"Complete\" or \"Failed\". Job cannot be both in the \"Complete\" and \"Failed\" conditions. Additionally, it cannot be in the \"Complete\" and \"FailureTarget\" conditions. The \"Complete\", \"Failed\" and \"FailureTarget\" conditions cannot be disabled.\n\nMore info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/",
"description": "The latest available observations of an object's current state. When a Job fails, one of the conditions will have type \"Failed\" and status true. When a Job is suspended, one of the conditions will have type \"Suspended\" and status true; when the Job is resumed, the status of this condition will become false. When a Job is completed, one of the conditions will have type \"Complete\" and status true.\n\nA job is considered finished when it is in a terminal condition, either \"Complete\" or \"Failed\". A Job cannot have both the \"Complete\" and \"Failed\" conditions. Additionally, it cannot be in the \"Complete\" and \"FailureTarget\" conditions. The \"Complete\", \"Failed\" and \"FailureTarget\" conditions cannot be disabled.\n\nMore info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/",
"items": {
"$ref": "#/definitions/io.k8s.api.batch.v1.JobCondition"
},

View File

@@ -435,7 +435,7 @@
"description": "Represents time when the job was completed. It is not guaranteed to be set in happens-before order across separate operations. It is represented in RFC3339 form and is in UTC. The completion time is set when the job finishes successfully, and only then. The value cannot be updated or removed. The value indicates the same or later point in time as the startTime field."
},
"conditions": {
"description": "The latest available observations of an object's current state. When a Job fails, one of the conditions will have type \"Failed\" and status true. When a Job is suspended, one of the conditions will have type \"Suspended\" and status true; when the Job is resumed, the status of this condition will become false. When a Job is completed, one of the conditions will have type \"Complete\" and status true.\n\nA job is considered finished when it is in a terminal condition, either \"Complete\" or \"Failed\". Job cannot be both in the \"Complete\" and \"Failed\" conditions. Additionally, it cannot be in the \"Complete\" and \"FailureTarget\" conditions. The \"Complete\", \"Failed\" and \"FailureTarget\" conditions cannot be disabled.\n\nMore info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/",
"description": "The latest available observations of an object's current state. When a Job fails, one of the conditions will have type \"Failed\" and status true. When a Job is suspended, one of the conditions will have type \"Suspended\" and status true; when the Job is resumed, the status of this condition will become false. When a Job is completed, one of the conditions will have type \"Complete\" and status true.\n\nA job is considered finished when it is in a terminal condition, either \"Complete\" or \"Failed\". A Job cannot have both the \"Complete\" and \"Failed\" conditions. Additionally, it cannot be in the \"Complete\" and \"FailureTarget\" conditions. The \"Complete\", \"Failed\" and \"FailureTarget\" conditions cannot be disabled.\n\nMore info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/",
"items": {
"allOf": [
{

View File

@@ -495,7 +495,7 @@ type JobStatus struct {
// type "Complete" and status true.
//
// A job is considered finished when it is in a terminal condition, either
// "Complete" or "Failed". Job cannot be both in the "Complete" and "Failed" conditions.
// "Complete" or "Failed". A Job cannot have both the "Complete" and "Failed" conditions.
// Additionally, it cannot be in the "Complete" and "FailureTarget" conditions.
// The "Complete", "Failed" and "FailureTarget" conditions cannot be disabled.
//

View File

@@ -524,11 +524,6 @@ func validateJobStatus(job *batch.Job, fldPath *field.Path, opts JobStatusValida
allErrs = append(allErrs, field.Invalid(fldPath.Child("active"), status.Active, "active>0 is invalid for finished job"))
}
}
if opts.RejectFinishedJobWithTerminatingPods {
if status.Terminating != nil && *status.Terminating > 0 && isJobFinished {
allErrs = append(allErrs, field.Invalid(fldPath.Child("terminating"), status.Terminating, "terminating>0 is invalid for finished job"))
}
}
if opts.RejectFinishedJobWithoutStartTime {
if status.StartTime == nil && isJobFinished {
allErrs = append(allErrs, field.Required(fldPath.Child("startTime"), "startTime is required for finished job"))
@@ -566,11 +561,6 @@ func validateJobStatus(job *batch.Job, fldPath *field.Path, opts JobStatusValida
allErrs = append(allErrs, field.Invalid(fldPath.Child("failedIndexes"), *status.FailedIndexes, "cannot set non-null failedIndexes when backoffLimitPerIndex is null"))
}
}
if opts.RejectMoreReadyThanActivePods {
if status.Ready != nil && *status.Ready > status.Active {
allErrs = append(allErrs, field.Invalid(fldPath.Child("ready"), *status.Ready, "cannot set more ready pods than active"))
}
}
if opts.RejectFailedIndexesOverlappingCompleted {
if job.Spec.Completions != nil && status.FailedIndexes != nil {
if err := validateFailedIndexesNotOverlapCompleted(status.CompletedIndexes, *status.FailedIndexes, int32(*job.Spec.Completions)); err != nil {
@@ -1023,9 +1013,7 @@ type JobStatusValidationOptions struct {
RejectFailedIndexesOverlappingCompleted bool
RejectCompletedIndexesForNonIndexedJob bool
RejectFailedIndexesForNoBackoffLimitPerIndex bool
RejectMoreReadyThanActivePods bool
RejectFinishedJobWithActivePods bool
RejectFinishedJobWithTerminatingPods bool
RejectFinishedJobWithoutStartTime bool
RejectFinishedJobWithUncountedTerminatedPods bool
RejectStartTimeUpdateForUnsuspendedJob bool

View File

@@ -17191,7 +17191,7 @@ func schema_k8sio_api_batch_v1_JobStatus(ref common.ReferenceCallback) common.Op
},
},
SchemaProps: spec.SchemaProps{
Description: "The latest available observations of an object's current state. When a Job fails, one of the conditions will have type \"Failed\" and status true. When a Job is suspended, one of the conditions will have type \"Suspended\" and status true; when the Job is resumed, the status of this condition will become false. When a Job is completed, one of the conditions will have type \"Complete\" and status true.\n\nA job is considered finished when it is in a terminal condition, either \"Complete\" or \"Failed\". Job cannot be both in the \"Complete\" and \"Failed\" conditions. Additionally, it cannot be in the \"Complete\" and \"FailureTarget\" conditions. The \"Complete\", \"Failed\" and \"FailureTarget\" conditions cannot be disabled.\n\nMore info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/",
Description: "The latest available observations of an object's current state. When a Job fails, one of the conditions will have type \"Failed\" and status true. When a Job is suspended, one of the conditions will have type \"Suspended\" and status true; when the Job is resumed, the status of this condition will become false. When a Job is completed, one of the conditions will have type \"Complete\" and status true.\n\nA job is considered finished when it is in a terminal condition, either \"Complete\" or \"Failed\". A Job cannot have both the \"Complete\" and \"Failed\" conditions. Additionally, it cannot be in the \"Complete\" and \"FailureTarget\" conditions. The \"Complete\", \"Failed\" and \"FailureTarget\" conditions cannot be disabled.\n\nMore info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/",
Type: []string{"array"},
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{

View File

@@ -380,8 +380,6 @@ func getStatusValidationOptions(newJob, oldJob *batch.Job) batchvalidation.JobSt
isCompletedIndexesChanged := oldJob.Status.CompletedIndexes != newJob.Status.CompletedIndexes
isFailedIndexesChanged := !ptr.Equal(oldJob.Status.FailedIndexes, newJob.Status.FailedIndexes)
isActiveChanged := oldJob.Status.Active != newJob.Status.Active
isReadyChanged := !ptr.Equal(oldJob.Status.Ready, newJob.Status.Ready)
isTerminatingChanged := !ptr.Equal(oldJob.Status.Terminating, newJob.Status.Terminating)
isStartTimeChanged := !ptr.Equal(oldJob.Status.StartTime, newJob.Status.StartTime)
isCompletionTimeChanged := !ptr.Equal(oldJob.Status.CompletionTime, newJob.Status.CompletionTime)
isUncountedTerminatedPodsChanged := !apiequality.Semantic.DeepEqual(oldJob.Status.UncountedTerminatedPods, newJob.Status.UncountedTerminatedPods)
@@ -397,9 +395,7 @@ func getStatusValidationOptions(newJob, oldJob *batch.Job) batchvalidation.JobSt
RejectCompletedIndexesForNonIndexedJob: isCompletedIndexesChanged,
RejectFailedIndexesForNoBackoffLimitPerIndex: isFailedIndexesChanged,
RejectFailedIndexesOverlappingCompleted: isFailedIndexesChanged || isCompletedIndexesChanged,
RejectMoreReadyThanActivePods: isReadyChanged || isActiveChanged,
RejectFinishedJobWithActivePods: isJobFinishedChanged || isActiveChanged,
RejectFinishedJobWithTerminatingPods: isJobFinishedChanged || isTerminatingChanged,
RejectFinishedJobWithoutStartTime: isJobFinishedChanged || isStartTimeChanged,
RejectFinishedJobWithUncountedTerminatedPods: isJobFinishedChanged || isUncountedTerminatedPodsChanged,
RejectStartTimeUpdateForUnsuspendedJob: isStartTimeChanged,

View File

@@ -2271,7 +2271,7 @@ func TestStatusStrategy_ValidateUpdate(t *testing.T) {
{Type: field.ErrorTypeInvalid, Field: "status.active"},
},
},
"invalid attempt to transition to Complete=True with terminating > 0": {
"transition to Failed condition with terminating>0 and ready>0": {
enableJobManagedBy: true,
job: &batch.Job{
ObjectMeta: validObjectMeta,
@@ -2280,19 +2280,16 @@ func TestStatusStrategy_ValidateUpdate(t *testing.T) {
ObjectMeta: validObjectMeta,
Status: batch.JobStatus{
StartTime: &now,
CompletionTime: &now,
Terminating: ptr.To[int32](1),
Conditions: []batch.JobCondition{
{
Type: batch.JobComplete,
Type: batch.JobFailed,
Status: api.ConditionTrue,
},
},
Terminating: ptr.To[int32](1),
Ready: ptr.To[int32](1),
},
},
wantErrs: field.ErrorList{
{Type: field.ErrorTypeInvalid, Field: "status.terminating"},
},
},
"invalid attempt to transition to Failed=True with uncountedTerminatedPods.Failed>0": {
enableJobManagedBy: true,
@@ -2929,28 +2926,6 @@ func TestStatusStrategy_ValidateUpdate(t *testing.T) {
},
},
},
"invalid attempt to set more ready pods than active": {
enableJobManagedBy: true,
job: &batch.Job{
ObjectMeta: validObjectMeta,
Spec: batch.JobSpec{
Completions: ptr.To[int32](5),
},
},
newJob: &batch.Job{
ObjectMeta: validObjectMeta,
Spec: batch.JobSpec{
Completions: ptr.To[int32](5),
},
Status: batch.JobStatus{
Active: 1,
Ready: ptr.To[int32](2),
},
},
wantErrs: field.ErrorList{
{Type: field.ErrorTypeInvalid, Field: "status.ready"},
},
},
"more ready pods than active, but allowed": {
enableJobManagedBy: true,
job: &batch.Job{

View File

@@ -367,7 +367,7 @@ message JobStatus {
// type "Complete" and status true.
//
// A job is considered finished when it is in a terminal condition, either
// "Complete" or "Failed". Job cannot be both in the "Complete" and "Failed" conditions.
// "Complete" or "Failed". A Job cannot have both the "Complete" and "Failed" conditions.
// Additionally, it cannot be in the "Complete" and "FailureTarget" conditions.
// The "Complete", "Failed" and "FailureTarget" conditions cannot be disabled.
//

View File

@@ -495,7 +495,7 @@ type JobStatus struct {
// type "Complete" and status true.
//
// A job is considered finished when it is in a terminal condition, either
// "Complete" or "Failed". Job cannot be both in the "Complete" and "Failed" conditions.
// "Complete" or "Failed". A Job cannot have both the "Complete" and "Failed" conditions.
// Additionally, it cannot be in the "Complete" and "FailureTarget" conditions.
// The "Complete", "Failed" and "FailureTarget" conditions cannot be disabled.
//

View File

@@ -136,7 +136,7 @@ func (JobSpec) SwaggerDoc() map[string]string {
var map_JobStatus = map[string]string{
"": "JobStatus represents the current state of a Job.",
"conditions": "The latest available observations of an object's current state. When a Job fails, one of the conditions will have type \"Failed\" and status true. When a Job is suspended, one of the conditions will have type \"Suspended\" and status true; when the Job is resumed, the status of this condition will become false. When a Job is completed, one of the conditions will have type \"Complete\" and status true.\n\nA job is considered finished when it is in a terminal condition, either \"Complete\" or \"Failed\". Job cannot be both in the \"Complete\" and \"Failed\" conditions. Additionally, it cannot be in the \"Complete\" and \"FailureTarget\" conditions. The \"Complete\", \"Failed\" and \"FailureTarget\" conditions cannot be disabled.\n\nMore info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/",
"conditions": "The latest available observations of an object's current state. When a Job fails, one of the conditions will have type \"Failed\" and status true. When a Job is suspended, one of the conditions will have type \"Suspended\" and status true; when the Job is resumed, the status of this condition will become false. When a Job is completed, one of the conditions will have type \"Complete\" and status true.\n\nA job is considered finished when it is in a terminal condition, either \"Complete\" or \"Failed\". A Job cannot have both the \"Complete\" and \"Failed\" conditions. Additionally, it cannot be in the \"Complete\" and \"FailureTarget\" conditions. The \"Complete\", \"Failed\" and \"FailureTarget\" conditions cannot be disabled.\n\nMore info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/",
"startTime": "Represents time when the job controller started processing a job. When a Job is created in the suspended state, this field is not set until the first time it is resumed. This field is reset every time a Job is resumed from suspension. It is represented in RFC3339 form and is in UTC.\n\nOnce set, the field can only be removed when the job is suspended. The field cannot be modified while the job is unsuspended or finished.",
"completionTime": "Represents time when the job was completed. It is not guaranteed to be set in happens-before order across separate operations. It is represented in RFC3339 form and is in UTC. The completion time is set when the job finishes successfully, and only then. The value cannot be updated or removed. The value indicates the same or later point in time as the startTime field.",
"active": "The number of pending and running pods which are not terminating (without a deletionTimestamp). The value is zero for finished jobs.",