diff --git a/internal/apis/compute/validation/machine.go b/internal/apis/compute/validation/machine.go index aa1ae9e59..f36f5e8e3 100644 --- a/internal/apis/compute/validation/machine.go +++ b/internal/apis/compute/validation/machine.go @@ -34,6 +34,22 @@ func ValidateMachine(machine *compute.Machine) field.ErrorList { func ValidateMachineUpdate(newMachine, oldMachine *compute.Machine) field.ErrorList { var allErrs field.ErrorList + seenVolumeNames := sets.NewString() + newVolumeNameIndexMap := map[string]int{} + for _, vol := range oldMachine.Spec.Volumes { + seenVolumeNames.Insert(vol.Name) + } + for index, vol := range newMachine.Spec.Volumes { + if !seenVolumeNames.Has(vol.Name) { + newVolumeNameIndexMap[vol.Name] = index + } + } + for _, vol := range newMachine.Status.Volumes { + if i, ok := newVolumeNameIndexMap[vol.Name]; ok { + allErrs = append(allErrs, field.Duplicate(field.NewPath("spec.volume").Index(i).Child("name"), vol.Name)) + } + } + allErrs = append(allErrs, apivalidation.ValidateObjectMetaAccessorUpdate(newMachine, oldMachine, field.NewPath("metadata"))...) allErrs = append(allErrs, validateMachineSpecUpdate(&newMachine.Spec, &oldMachine.Spec, field.NewPath("spec"))...) allErrs = append(allErrs, ValidateMachine(newMachine)...) diff --git a/internal/apis/compute/validation/machine_test.go b/internal/apis/compute/validation/machine_test.go index a658f0ecf..33282c21b 100644 --- a/internal/apis/compute/validation/machine_test.go +++ b/internal/apis/compute/validation/machine_test.go @@ -474,5 +474,35 @@ var _ = Describe("Machine", func() { &compute.Machine{}, Not(ContainElement(ImmutableField("spec.machinePoolRef"))), ), + Entry("duplicate volume name", + &compute.Machine{ + Spec: compute.MachineSpec{ + Volumes: []compute.Volume{ + {Name: "foo"}, + {Name: "bar"}, + }, + }, + Status: compute.MachineStatus{ + Volumes: []compute.VolumeStatus{ + {Name: "foo"}, + {Name: "bar"}, + }, + }, + }, + &compute.Machine{ + Spec: compute.MachineSpec{ + Volumes: []compute.Volume{ + {Name: "foo"}, + }, + }, + Status: compute.MachineStatus{ + Volumes: []compute.VolumeStatus{ + {Name: "foo"}, + {Name: "bar"}, + }, + }, + }, + ContainElement(DuplicateField("spec.volume[1].name")), + ), ) }) diff --git a/poollet/machinepoollet/controllers/machine_controller_volume.go b/poollet/machinepoollet/controllers/machine_controller_volume.go index 62fa8981f..121118c79 100644 --- a/poollet/machinepoollet/controllers/machine_controller_volume.go +++ b/poollet/machinepoollet/controllers/machine_controller_volume.go @@ -385,30 +385,35 @@ func (r *MachineReconciler) getVolumeStatusesForMachine( errs []error ) + for _, iriVolume := range iriMachine.Status.Volumes { + var volumeStatusValues computev1alpha1.VolumeStatus + volumeStatusValues, err := r.convertIRIVolumeStatus(iriVolume, iriVolume.Name) + if err != nil { + return nil, fmt.Errorf("[volume %s] %w", iriVolume.Name, err) + } + volumeStatus := existingVolumeStatusesByName[iriVolume.Name] + r.addVolumeStatusValues(now, &volumeStatus, &volumeStatusValues) + volumeStatuses = append(volumeStatuses, volumeStatus) + } + for _, machineVolume := range machine.Spec.Volumes { var ( - iriVolumeStatus, ok = iriVolumeStatusByName[machineVolume.Name] - volumeStatusValues computev1alpha1.VolumeStatus + _, ok = iriVolumeStatusByName[machineVolume.Name] + volumeStatusValues computev1alpha1.VolumeStatus ) volumeName := computev1alpha1.MachineVolumeName(machine.Name, machineVolume) - if ok { - var err error - volumeStatusValues, err = r.convertIRIVolumeStatus(iriVolumeStatus, volumeName) - if err != nil { - return nil, fmt.Errorf("[volume %s] %w", machineVolume.Name, err) - } - } else { + if !ok { volumeStatusValues = computev1alpha1.VolumeStatus{ Name: machineVolume.Name, State: computev1alpha1.VolumeStatePending, VolumeRef: corev1.LocalObjectReference{Name: volumeName}, } + volumeStatus := existingVolumeStatusesByName[machineVolume.Name] + r.addVolumeStatusValues(now, &volumeStatus, &volumeStatusValues) + volumeStatuses = append(volumeStatuses, volumeStatus) } - - volumeStatus := existingVolumeStatusesByName[machineVolume.Name] - r.addVolumeStatusValues(now, &volumeStatus, &volumeStatusValues) - volumeStatuses = append(volumeStatuses, volumeStatus) } + if len(errs) > 0 { return nil, errors.Join(errs...) }