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  }