Skip to content

Commit 80ac7ee

Browse files
RoncossekAndreasBurger
authored andcommitted
refactor: simplify region validation logic for machine images
1 parent 331fbe8 commit 80ac7ee

2 files changed

Lines changed: 19 additions & 43 deletions

File tree

pkg/apis/aws/validation/cloudprofile.go

Lines changed: 11 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,12 @@ func validateMachineImageVersion(providerImage apisaws.MachineImages, capability
9494
} else if hasCapabilityFlavors {
9595
allErrs = append(allErrs, validateCapabilityFlavors(providerImage, version, capabilityDefinitions, jdxPath)...)
9696
} else {
97-
// Using old format with regions - validate regions without architecture restriction (architecture is validated separately)
98-
allErrs = append(allErrs, validateRegionsWithCapabilities(version.Regions, providerImage.Name, version.Version, jdxPath)...)
97+
// Using old format with regions
98+
allErrs = append(allErrs, validateRegions(version.Regions, providerImage.Name, version.Version, false, jdxPath)...)
9999
}
100100
} else {
101101
// Without capabilities, only old format with regions is supported
102-
allErrs = append(allErrs, validateRegions(version.Regions, providerImage.Name, version.Version, capabilityDefinitions, jdxPath)...)
102+
allErrs = append(allErrs, validateRegions(version.Regions, providerImage.Name, version.Version, false, jdxPath)...)
103103
if hasCapabilityFlavors {
104104
allErrs = append(allErrs, field.Forbidden(jdxPath.Child("capabilityFlavors"), "must not be set as CloudProfile does not define capabilities. Use regions instead."))
105105
}
@@ -115,66 +115,37 @@ func validateCapabilityFlavors(providerImage apisaws.MachineImages, version apis
115115
for k, capabilitySet := range version.CapabilityFlavors {
116116
kdxPath := jdxPath.Child("capabilityFlavors").Index(k)
117117
allErrs = append(allErrs, gutil.ValidateCapabilities(capabilitySet.Capabilities, capabilityDefinitions, kdxPath.Child("capabilities"))...)
118-
allErrs = append(allErrs, validateRegions(capabilitySet.Regions, providerImage.Name, version.Version, capabilityDefinitions, kdxPath)...)
119-
}
120-
return allErrs
121-
}
122-
123-
// validateRegionsWithCapabilities validates regions when using old format with capabilities CloudProfile.
124-
// This allows architecture field in regions since it will be converted to capability flavors.
125-
func validateRegionsWithCapabilities(regions []apisaws.RegionAMIMapping, name, version string, jdxPath *field.Path) field.ErrorList {
126-
allErrs := field.ErrorList{}
127-
if len(regions) == 0 {
128-
return append(allErrs, field.Required(jdxPath.Child("regions"), fmt.Sprintf("must provide at least one region for machine image %q and version %q", name, version)))
129-
}
130-
131-
for k, region := range regions {
132-
kdxPath := jdxPath.Child("regions").Index(k)
133-
arch := ptr.Deref(region.Architecture, v1beta1constants.ArchitectureAMD64)
134-
135-
if len(region.Name) == 0 {
136-
allErrs = append(allErrs, field.Required(kdxPath.Child("name"), "must provide a name"))
137-
}
138-
if len(region.AMI) == 0 {
139-
allErrs = append(allErrs, field.Required(kdxPath.Child("ami"), "must provide an ami"))
140-
}
141-
// Validate architecture is valid since it will be used for capability mapping
142-
if !slices.Contains(v1beta1constants.ValidArchitectures, arch) {
143-
allErrs = append(allErrs, field.NotSupported(kdxPath.Child("architecture"), arch, v1beta1constants.ValidArchitectures))
144-
}
118+
allErrs = append(allErrs, validateRegions(capabilitySet.Regions, providerImage.Name, version.Version, true, kdxPath)...)
145119
}
146120
return allErrs
147121
}
148122

149123
// validateRegions validates the regions of a machine image version or capability flavor.
150-
func validateRegions(regions []apisaws.RegionAMIMapping, name, version string, capabilityDefinitions []gardencorev1beta1.CapabilityDefinition, jdxPath *field.Path) field.ErrorList {
124+
func validateRegions(regions []apisaws.RegionAMIMapping, name, version string, isCapabilityFlavor bool, jdxPath *field.Path) field.ErrorList {
151125
allErrs := field.ErrorList{}
152126
if len(regions) == 0 {
153127
return append(allErrs, field.Required(jdxPath.Child("regions"), fmt.Sprintf("must provide at least one region for machine image %q and version %q", name, version)))
154128
}
155129

156130
for k, region := range regions {
157131
kdxPath := jdxPath.Child("regions").Index(k)
158-
arch := ptr.Deref(region.Architecture, v1beta1constants.ArchitectureAMD64)
159132

160133
if len(region.Name) == 0 {
161134
allErrs = append(allErrs, field.Required(kdxPath.Child("name"), "must provide a name"))
162135
}
163136
if len(region.AMI) == 0 {
164137
allErrs = append(allErrs, field.Required(kdxPath.Child("ami"), "must provide an ami"))
165138
}
166-
if len(capabilityDefinitions) == 0 {
139+
if isCapabilityFlavor {
140+
if region.Architecture != nil {
141+
allErrs = append(allErrs, field.Forbidden(kdxPath.Child("architecture"), "must not be set in capability flavor regions as architecture is defined via capabilities"))
142+
}
143+
} else {
144+
arch := ptr.Deref(region.Architecture, v1beta1constants.ArchitectureAMD64)
167145
if !slices.Contains(v1beta1constants.ValidArchitectures, arch) {
168146
allErrs = append(allErrs, field.NotSupported(kdxPath.Child("architecture"), arch, v1beta1constants.ValidArchitectures))
169147
}
170148
}
171-
// This should be commented in once the defaulting of the architecture field is implemented via mutating webhook
172-
// currently there is no way to distinguish between a user set architecture and the default one
173-
if len(capabilityDefinitions) > 0 {
174-
if region.Architecture != nil {
175-
allErrs = append(allErrs, field.Forbidden(kdxPath.Child("architecture"), "must be defined in .capabilities.architecture"))
176-
}
177-
}
178149
}
179150
return allErrs
180151
}

pkg/apis/aws/validation/worker.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ func ValidateWorkersAgainstCloudProfileOnUpdate(
193193
fldPath *field.Path,
194194
) field.ErrorList {
195195
allErrs := field.ErrorList{}
196+
// Normalize capability definitions once at the entry point.
197+
// This ensures all downstream code can assume capabilities are always present.
198+
normalizedCapabilityDefinitions := apisawshelper.NormalizeCapabilityDefinitions(capabilityDefinitions)
196199

197200
// Validate the existence of the images the new/updated workers are to use. Validating the images used by old workers is not possible at this point, as they might
198201
// have been removed from the CloudProfile already.
@@ -211,8 +214,10 @@ func ValidateWorkersAgainstCloudProfileOnUpdate(
211214
allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("machine", "type"), w.Machine.Type, " not found in cloud profile"))
212215
continue
213216
}
217+
// Normalize machine type capabilities to include architecture
218+
machineTypeCapabilities := apisawshelper.NormalizeMachineTypeCapabilities(machineType.Capabilities, w.Machine.Architecture, normalizedCapabilityDefinitions)
214219

215-
allErrs = append(allErrs, validateWorkerConfigAgainstCloudProfile(newWorker, region, awsCloudProfile, machineType.Capabilities, capabilityDefinitions, fldPath.Index(i))...)
220+
allErrs = append(allErrs, validateWorkerConfigAgainstCloudProfile(newWorker, region, awsCloudProfile, machineTypeCapabilities, normalizedCapabilityDefinitions, fldPath.Index(i))...)
216221
}
217222
}
218223

@@ -223,7 +228,7 @@ func validateWorkerConfigAgainstCloudProfile(
223228
worker core.Worker,
224229
region string,
225230
awsCloudProfile *apisaws.CloudProfileConfig,
226-
machineCapabilities v1beta1.Capabilities,
231+
machineTypeCapabilities v1beta1.Capabilities,
227232
capabilityDefinitions []v1beta1.CapabilityDefinition,
228233
fldPath *field.Path,
229234
) field.ErrorList {
@@ -236,7 +241,7 @@ func validateWorkerConfigAgainstCloudProfile(
236241
return allErrs
237242
}
238243

239-
if _, err := apisawshelper.FindImageInCloudProfile(awsCloudProfile, image.Name, image.Version, region, machineCapabilities, capabilityDefinitions); err != nil {
244+
if _, err := apisawshelper.FindImageInCloudProfile(awsCloudProfile, image.Name, image.Version, region, machineTypeCapabilities, capabilityDefinitions); err != nil {
240245
allErrs = append(allErrs, field.Invalid(fldPath.Child("machine", "image"), image, fmt.Sprint(err)))
241246
}
242247
return allErrs

0 commit comments

Comments
 (0)