github.com/ironcore-dev/gardener-extension-provider-ironcore@v0.3.2-0.20240314231816-8336447fb9a0/pkg/apis/ironcore/validation/cloudprofile_test.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 "github.com/gardener/gardener/pkg/apis/core" 8 . "github.com/onsi/ginkgo/v2" 9 . "github.com/onsi/gomega" 10 . "github.com/onsi/gomega/gstruct" 11 "github.com/onsi/gomega/types" 12 "k8s.io/apimachinery/pkg/util/validation/field" 13 "k8s.io/utils/ptr" 14 15 apisironcore "github.com/ironcore-dev/gardener-extension-provider-ironcore/pkg/apis/ironcore" 16 ) 17 18 func InvalidField(fld string) types.GomegaMatcher { 19 return SimpleMatchField(field.ErrorTypeInvalid, fld) 20 } 21 22 func SimpleMatchField(errorType field.ErrorType, fld string) types.GomegaMatcher { 23 return HaveValue(MatchFields(IgnoreExtras, Fields{ 24 "Type": Equal(errorType), 25 "Field": Equal(fld), 26 })) 27 } 28 29 var _ = Describe("CloudProfileConfig validation", func() { 30 Describe("#ValidateCloudProfileConfig", func() { 31 var ( 32 cloudProfileConfig *apisironcore.CloudProfileConfig 33 machineImages []core.MachineImage 34 nilPath *field.Path 35 machineImageName string 36 machineImageVersion string 37 ) 38 39 BeforeEach(func() { 40 machineImageName = "ubuntu" 41 machineImageVersion = "1.2.3" 42 cloudProfileConfig = &apisironcore.CloudProfileConfig{ 43 MachineImages: []apisironcore.MachineImages{ 44 { 45 Name: machineImageName, 46 Versions: []apisironcore.MachineImageVersion{ 47 { 48 Version: machineImageVersion, 49 Image: "registry/image:sha1234", 50 Architecture: ptr.To[string]("amd64"), 51 }, 52 }, 53 }, 54 }, 55 StorageClasses: apisironcore.StorageClasses{ 56 Default: &apisironcore.StorageClass{ 57 Name: "default", 58 Type: "defaultType", 59 }, 60 Additional: []apisironcore.StorageClass{ 61 { 62 Name: "foo", 63 Type: "fooType", 64 }, 65 { 66 Name: "bar", 67 Type: "barType", 68 }, 69 }, 70 }, 71 } 72 machineImages = []core.MachineImage{ 73 { 74 Name: machineImageName, 75 Versions: []core.MachineImageVersion{ 76 { 77 ExpirableVersion: core.ExpirableVersion{Version: machineImageVersion}, 78 }, 79 }, 80 }, 81 } 82 }) 83 84 Describe("machine image validation", func() { 85 It("should pass validation", func() { 86 errorList := ValidateCloudProfileConfig(cloudProfileConfig, machineImages, nilPath) 87 Expect(errorList).To(BeEmpty()) 88 }) 89 90 It("should not require a machine image mapping because no versions are configured", func() { 91 machineImages = append(machineImages, core.MachineImage{ 92 Name: "suse", 93 Versions: nil, 94 }) 95 errorList := ValidateCloudProfileConfig(cloudProfileConfig, machineImages, nilPath) 96 Expect(errorList).To(BeEmpty()) 97 }) 98 99 It("should require a machine image mapping to be configured", func() { 100 machineImages = append(machineImages, core.MachineImage{ 101 Name: "suse", 102 Versions: []core.MachineImageVersion{ 103 { 104 ExpirableVersion: core.ExpirableVersion{ 105 Version: machineImageVersion, 106 }, 107 }, 108 }, 109 }) 110 errorList := ValidateCloudProfileConfig(cloudProfileConfig, machineImages, nilPath) 111 Expect(errorList).To(ConsistOf( 112 PointTo(MatchFields(IgnoreExtras, Fields{ 113 "Type": Equal(field.ErrorTypeRequired), 114 "Field": Equal("machineImages"), 115 })), 116 )) 117 }) 118 119 It("should forbid unsupported machine image version configuration", func() { 120 cloudProfileConfig.MachineImages[0].Versions[0].Image = "" 121 cloudProfileConfig.MachineImages[0].Versions[0].Architecture = ptr.To[string]("foo") 122 machineImages[0].Versions = append(machineImages[0].Versions, core.MachineImageVersion{ExpirableVersion: core.ExpirableVersion{Version: "2.0.0"}}) 123 errorList := ValidateCloudProfileConfig(cloudProfileConfig, machineImages, nilPath) 124 125 Expect(errorList).To(ConsistOf( 126 PointTo(MatchFields(IgnoreExtras, Fields{ 127 "Type": Equal(field.ErrorTypeRequired), 128 "Field": Equal("machineImages[0].versions"), 129 })), 130 PointTo(MatchFields(IgnoreExtras, Fields{ 131 "Type": Equal(field.ErrorTypeRequired), 132 "Field": Equal("machineImages[0].versions[0].image"), 133 })), 134 PointTo(MatchFields(IgnoreExtras, Fields{ 135 "Type": Equal(field.ErrorTypeNotSupported), 136 "Field": Equal("machineImages[0].versions[0].architecture"), 137 })), 138 )) 139 }) 140 }) 141 142 DescribeTable("ValidateCloudProfileConfig StorageClass name", 143 func(cpConfig *apisironcore.CloudProfileConfig, machineImages []core.MachineImage, fldPath *field.Path, match types.GomegaMatcher) { 144 errList := ValidateCloudProfileConfig(cpConfig, machineImages, fldPath) 145 Expect(errList).To(match) 146 }, 147 Entry("invalid storageClass name in default StorageClass", 148 &apisironcore.CloudProfileConfig{ 149 StorageClasses: apisironcore.StorageClasses{ 150 Default: &apisironcore.StorageClass{ 151 Name: "foo*", 152 Type: "defaultType", 153 }, 154 }, 155 }, 156 machineImages, 157 nilPath, 158 ContainElement(InvalidField("storageClasses.defaultStorageClasses.name")), 159 ), 160 Entry("invalid storageClass name in additional storageClasses", 161 &apisironcore.CloudProfileConfig{ 162 StorageClasses: apisironcore.StorageClasses{ 163 Additional: []apisironcore.StorageClass{ 164 { 165 Name: "foo*", 166 Type: "defaultType", 167 }, 168 }, 169 }, 170 }, 171 machineImages, 172 nilPath, 173 ContainElement(InvalidField("storageClasses.additionalStorageClasses[0].name")), 174 ), 175 ) 176 177 }) 178 })