github.com/ironcore-dev/gardener-extension-provider-ironcore@v0.3.2-0.20240314231816-8336447fb9a0/pkg/apis/ironcore/validation/cloudprofile.go (about) 1 // SPDX-FileCopyrightText: 2022 SAP SE or an SAP affiliate company and IronCore contributors 2 // SPDX-License-Identifier: Apache-2.0 3 4 package validation 5 6 import ( 7 "fmt" 8 9 gardenercore "github.com/gardener/gardener/pkg/apis/core" 10 gardenercorehelper "github.com/gardener/gardener/pkg/apis/core/helper" 11 v1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants" 12 apivalidation "k8s.io/apimachinery/pkg/api/validation" 13 "k8s.io/apimachinery/pkg/util/validation/field" 14 "k8s.io/utils/strings/slices" 15 16 apisironcore "github.com/ironcore-dev/gardener-extension-provider-ironcore/pkg/apis/ironcore" 17 ) 18 19 // ValidateCloudProfileConfig validates a CloudProfileConfig object. 20 func ValidateCloudProfileConfig(cpConfig *apisironcore.CloudProfileConfig, machineImages []gardenercore.MachineImage, fldPath *field.Path) field.ErrorList { 21 allErrs := field.ErrorList{} 22 machineImagesPath := fldPath.Child("machineImages") 23 24 for _, image := range machineImages { 25 var processed bool 26 for i, imageConfig := range cpConfig.MachineImages { 27 if image.Name == imageConfig.Name { 28 allErrs = append(allErrs, validateVersions(imageConfig.Versions, gardenercorehelper.ToExpirableVersions(image.Versions), machineImagesPath.Index(i).Child("versions"))...) 29 processed = true 30 break 31 } 32 } 33 if !processed && len(image.Versions) > 0 { 34 allErrs = append(allErrs, field.Required(machineImagesPath, fmt.Sprintf("must provide an image mapping for image %q", image.Name))) 35 } 36 } 37 38 if cpConfig.StorageClasses.Default != nil { 39 for _, msg := range apivalidation.NameIsDNSLabel(cpConfig.StorageClasses.Default.Name, false) { 40 allErrs = append(allErrs, field.Invalid(fldPath.Child("storageClasses").Child("defaultStorageClasses").Child("name"), cpConfig.StorageClasses.Default.Name, msg)) 41 } 42 } 43 44 for i, sc := range cpConfig.StorageClasses.Additional { 45 for _, msg := range apivalidation.NameIsDNSLabel(sc.Name, false) { 46 allErrs = append(allErrs, field.Invalid(fldPath.Child("storageClasses").Child("additionalStorageClasses").Index(i).Child("name"), sc.Name, msg)) 47 } 48 } 49 50 return allErrs 51 } 52 53 func validateVersions(versionsConfig []apisironcore.MachineImageVersion, versions []gardenercore.ExpirableVersion, fldPath *field.Path) field.ErrorList { 54 allErrs := field.ErrorList{} 55 56 for _, version := range versions { 57 var processed bool 58 for j, versionConfig := range versionsConfig { 59 jdxPath := fldPath.Index(j) 60 if version.Version == versionConfig.Version { 61 if len(versionConfig.Image) == 0 { 62 allErrs = append(allErrs, field.Required(jdxPath.Child("image"), "must provide an image")) 63 } 64 if !slices.Contains(v1beta1constants.ValidArchitectures, *versionConfig.Architecture) { 65 allErrs = append(allErrs, field.NotSupported(jdxPath.Child("architecture"), *versionConfig.Architecture, v1beta1constants.ValidArchitectures)) 66 } 67 processed = true 68 break 69 } 70 } 71 if !processed { 72 allErrs = append(allErrs, field.Required(fldPath, fmt.Sprintf("must provide an image mapping for version %q", version.Version))) 73 } 74 } 75 76 return allErrs 77 }