github.com/openshift/installer@v1.4.17/pkg/asset/imagebased/image/imagebased_config_test.go (about) 1 package image 2 3 import ( 4 "errors" 5 "os" 6 "os/exec" 7 "testing" 8 9 "github.com/golang/mock/gomock" 10 "github.com/stretchr/testify/assert" 11 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 12 "sigs.k8s.io/yaml" 13 14 aiv1beta1 "github.com/openshift/assisted-service/api/v1beta1" 15 "github.com/openshift/installer/pkg/asset" 16 "github.com/openshift/installer/pkg/asset/mock" 17 "github.com/openshift/installer/pkg/types" 18 "github.com/openshift/installer/pkg/types/imagebased" 19 ) 20 21 var ( 22 rawNMStateConfig = ` 23 interfaces: 24 - name: eth0 25 type: ethernet 26 state: up 27 mac-address: 00:00:00:00:00:00 28 ipv4: 29 enabled: true 30 address: 31 - ip: 192.168.122.2 32 prefix-length: 23 33 dhcp: false` 34 ) 35 36 func TestImageBasedInstallConfig_LoadedFromDisk(t *testing.T) { 37 skipTestIfnmstatectlIsMissing(t) 38 39 cases := []struct { 40 name string 41 data string 42 fetchError error 43 44 expectedError string 45 expectedFound bool 46 expectedConfig *ImageBasedInstallationConfigBuilder 47 }{ 48 { 49 name: "valid-config-single-node", 50 data: ` 51 apiVersion: v1beta1 52 metadata: 53 name: image-based-installation-config 54 pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" 55 seedImage: quay.io/openshift-kni/seed-image:4.16.0 56 seedVersion: 4.16.0 57 installationDisk: /dev/vda 58 networkConfig: 59 interfaces: 60 - name: eth0 61 type: ethernet 62 state: up 63 mac-address: 00:00:00:00:00:00 64 ipv4: 65 enabled: true 66 address: 67 - ip: 192.168.122.2 68 prefix-length: 23 69 dhcp: false 70 `, 71 72 expectedFound: true, 73 expectedConfig: ibiConfig(), 74 }, 75 { 76 name: "not-yaml", 77 data: `This is not a yaml file`, 78 79 expectedFound: false, 80 expectedError: "failed to unmarshal image-based-installation-config.yaml: error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go value of type imagebased.InstallationConfig", 81 }, 82 { 83 name: "file-not-found", 84 fetchError: &os.PathError{Err: os.ErrNotExist}, 85 86 expectedFound: false, 87 }, 88 { 89 name: "error-fetching-file", 90 fetchError: errors.New("fetch failed"), 91 92 expectedFound: false, 93 expectedError: "failed to load image-based-installation-config.yaml file: fetch failed", 94 }, 95 { 96 name: "unknown-field", 97 data: ` 98 apiVersion: v1beta1 99 metadata: 100 name: image-based-installation-config 101 wrongField: wrongValue`, 102 103 expectedFound: false, 104 expectedError: "failed to unmarshal image-based-installation-config.yaml: error unmarshaling JSON: while decoding JSON: json: unknown field \"wrongField\"", 105 }, 106 { 107 name: "empty-pullSecret", 108 data: ` 109 apiVersion: v1beta1 110 metadata: 111 name: image-based-installation-config 112 seedVersion: 4.16.0 113 seedImage: quay.io/openshift-kni/seed-image:4.16.0 114 installationDisk: /dev/vda`, 115 116 expectedFound: false, 117 expectedError: "invalid Image-based Installation ISO Config: pullSecret: Required value: you must specify a pullSecret", 118 }, 119 { 120 name: "invalid-pullSecret", 121 data: ` 122 apiVersion: v1beta1 123 metadata: 124 name: image-based-installation-config 125 pullSecret: "{\"missing\":\"auths\"}" 126 seedVersion: 4.16.0 127 seedImage: quay.io/openshift-kni/seed-image:4.16.0 128 installationDisk: /dev/vda`, 129 130 expectedFound: false, 131 expectedError: "invalid Image-based Installation ISO Config: pullSecret: Invalid value: \"{\\\"missing\\\":\\\"auths\\\"}\": auths required", 132 }, 133 { 134 name: "invalid-sshKey", 135 data: ` 136 apiVersion: v1beta1 137 metadata: 138 name: image-based-installation-config 139 pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" 140 seedVersion: 4.16.0 141 seedImage: quay.io/openshift-kni/seed-image:4.16.0 142 installationDisk: /dev/vda 143 sshKey: invalid_ssh_key`, 144 145 expectedFound: false, 146 expectedError: "invalid Image-based Installation ISO Config: sshKey: Invalid value: \"invalid_ssh_key\": ssh: no key found", 147 }, 148 { 149 name: "empty-seedVersion", 150 data: ` 151 apiVersion: v1beta1 152 metadata: 153 name: image-based-installation-config 154 pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" 155 seedImage: quay.io/openshift-kni/seed-image:4.16.0 156 installationDisk: /dev/vda`, 157 158 expectedFound: false, 159 expectedError: "invalid Image-based Installation ISO Config: seedVersion: Required value: you must specify a seedVersion", 160 }, 161 { 162 name: "empty-seedImage", 163 data: ` 164 apiVersion: v1beta1 165 metadata: 166 name: image-based-installation-config 167 pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" 168 seedVersion: 4.16.0 169 installationDisk: /dev/vda`, 170 171 expectedFound: false, 172 expectedError: "invalid Image-based Installation ISO Config: seedImage: Required value: you must specify a seedImage", 173 }, 174 { 175 name: "empty-installationDisk", 176 data: ` 177 apiVersion: v1beta1 178 metadata: 179 name: image-based-installation-config 180 pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" 181 seedImage: "quay.io/openshift-kni/seed-image:4.16.0" 182 seedVersion: "4.16.0"`, 183 184 expectedFound: false, 185 expectedError: "invalid Image-based Installation ISO Config: installationDisk: Required value: you must specify an installationDisk", 186 }, 187 { 188 name: "invalid-additionalTrustBundle", 189 data: ` 190 apiVersion: v1beta1 191 metadata: 192 name: image-based-installation-config 193 pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" 194 seedVersion: 4.16.0 195 seedImage: quay.io/openshift-kni/seed-image:4.16.0 196 installationDisk: /dev/vda 197 additionalTrustBundle: invalid_cert 198 `, 199 200 expectedFound: false, 201 expectedError: "invalid Image-based Installation ISO Config: additionalTrustBundle: Invalid value: \"invalid_cert\": invalid block", 202 }, 203 { 204 name: "invalid-networkConfig", 205 data: ` 206 apiVersion: v1beta1 207 metadata: 208 name: image-based-installation-config 209 pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" 210 seedVersion: 4.16.0 211 seedImage: quay.io/openshift-kni/seed-image:4.16.0 212 installationDisk: /dev/vda 213 networkConfig: 214 invalid: config 215 `, 216 217 expectedFound: false, 218 expectedError: "networkConfig: Invalid value: invalid: config\n: failed to execute 'nmstatectl gc', error: InvalidArgument: Invalid YAML string: unknown field `invalid`", 219 }, 220 { 221 name: "invalid-imageDigestSources", 222 data: ` 223 apiVersion: v1beta1 224 metadata: 225 name: image-based-installation-config 226 pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" 227 seedVersion: 4.16.0 228 seedImage: quay.io/openshift-kni/seed-image:4.16.0 229 installationDisk: /dev/vda 230 imageDigestSources: 231 - source: quay.io 232 mirrors: 233 - Registry.lab.redhat.com:5000 234 `, 235 236 expectedFound: false, 237 expectedError: "invalid Image-based Installation ISO Config: imageDigestSources[0].mirrors[0]: Invalid value: \"Registry.lab.redhat.com:5000\": failed to parse: invalid reference format: repository name must be lowercase", 238 }, 239 { 240 name: "invalid-proxy-schemes", 241 data: ` 242 apiVersion: v1beta1 243 metadata: 244 name: image-based-installation-config 245 pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" 246 seedVersion: 4.16.0 247 seedImage: quay.io/openshift-kni/seed-image:4.16.0 248 installationDisk: /dev/vda 249 proxy: 250 httpProxy: "" 251 httpsProxy: "" 252 noProxy: "" 253 `, 254 255 expectedFound: false, 256 expectedError: "invalid Image-based Installation ISO Config: proxy: Required value: must include httpProxy or httpsProxy", 257 }, 258 { 259 name: "invalid-proxy-http-uri", 260 data: ` 261 apiVersion: v1beta1 262 metadata: 263 name: image-based-installation-config 264 pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" 265 seedVersion: 4.16.0 266 seedImage: quay.io/openshift-kni/seed-image:4.16.0 267 installationDisk: /dev/vda 268 proxy: 269 httpProxy: "invalidscheme://" 270 httpsProxy: "" 271 noProxy: "" 272 `, 273 274 expectedFound: false, 275 expectedError: "invalid Image-based Installation ISO Config: proxy.httpProxy: Unsupported value: \"invalidscheme\": supported values: \"http\"", 276 }, 277 { 278 name: "invalid-proxy-https-uri", 279 data: ` 280 apiVersion: v1beta1 281 metadata: 282 name: image-based-installation-config 283 pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" 284 seedVersion: 4.16.0 285 seedImage: quay.io/openshift-kni/seed-image:4.16.0 286 installationDisk: /dev/vda 287 proxy: 288 httpProxy: "" 289 httpsProxy: "invalidscheme://" 290 noProxy: "" 291 `, 292 293 expectedFound: false, 294 expectedError: "invalid Image-based Installation ISO Config: proxy.httpsProxy: Unsupported value: \"invalidscheme\": supported values: \"http\", \"https\"", 295 }, 296 } 297 for _, tc := range cases { 298 t.Run(tc.name, func(t *testing.T) { 299 mockCtrl := gomock.NewController(t) 300 defer mockCtrl.Finish() 301 302 fileFetcher := mock.NewMockFileFetcher(mockCtrl) 303 fileFetcher.EXPECT().FetchByName(configFilename). 304 Return( 305 &asset.File{ 306 Filename: configFilename, 307 Data: []byte(tc.data)}, 308 tc.fetchError, 309 ) 310 311 asset := &ImageBasedInstallationConfig{} 312 found, err := asset.Load(fileFetcher) 313 assert.Equal(t, tc.expectedFound, found) 314 if tc.expectedError != "" { 315 assert.ErrorContains(t, err, tc.expectedError) 316 } else { 317 assert.NoError(t, err) 318 if tc.expectedConfig != nil { 319 assert.Equal(t, tc.expectedConfig.build(), asset.Config, "unexpected Config in ImageBasedInstallConfig") 320 } 321 } 322 }) 323 } 324 } 325 326 // ImageBasedInstallationConfigBuilder it's a builder class to make it easier 327 // creating imagebased.InstallationConfig instance used in the test cases. 328 type ImageBasedInstallationConfigBuilder struct { 329 imagebased.InstallationConfig 330 } 331 332 func ibiConfig() *ImageBasedInstallationConfigBuilder { 333 return &ImageBasedInstallationConfigBuilder{ 334 InstallationConfig: imagebased.InstallationConfig{ 335 ObjectMeta: metav1.ObjectMeta{ 336 Name: "image-based-installation-config", 337 }, 338 TypeMeta: metav1.TypeMeta{ 339 APIVersion: imagebased.ImageBasedConfigVersion, 340 }, 341 SeedImage: "quay.io/openshift-kni/seed-image:4.16.0", 342 SeedVersion: "4.16.0", 343 InstallationDisk: "/dev/vda", 344 ExtraPartitionStart: "-40G", 345 ExtraPartitionLabel: "varlibcontainers", 346 ExtraPartitionNumber: 5, 347 Shutdown: false, 348 SSHKey: "", 349 PullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}", 350 NetworkConfig: aiv1beta1.NetConfig{ 351 Raw: unmarshalJSON([]byte(rawNMStateConfig)), 352 }, 353 }, 354 } 355 } 356 357 func (icb *ImageBasedInstallationConfigBuilder) build() *imagebased.InstallationConfig { 358 return &icb.InstallationConfig 359 } 360 361 func (icb *ImageBasedInstallationConfigBuilder) additionalTrustBundle(atb string) *ImageBasedInstallationConfigBuilder { 362 icb.InstallationConfig.AdditionalTrustBundle = atb 363 return icb 364 } 365 366 func (icb *ImageBasedInstallationConfigBuilder) networkConfig(nc aiv1beta1.NetConfig) *ImageBasedInstallationConfigBuilder { 367 icb.InstallationConfig.NetworkConfig = nc 368 return icb 369 } 370 371 func (icb *ImageBasedInstallationConfigBuilder) imageDigestSources(ids []types.ImageDigestSource) *ImageBasedInstallationConfigBuilder { 372 icb.InstallationConfig.ImageDigestSources = ids 373 return icb 374 } 375 376 func (icb *ImageBasedInstallationConfigBuilder) ignitionConfigOverride(ignitionConfigOverride string) *ImageBasedInstallationConfigBuilder { 377 icb.InstallationConfig.IgnitionConfigOverride = ignitionConfigOverride 378 return icb 379 } 380 381 func unmarshalJSON(b []byte) []byte { 382 output, err := yaml.JSONToYAML(b) 383 if err != nil { 384 return nil 385 } 386 return output 387 } 388 389 func skipTestIfnmstatectlIsMissing(t *testing.T) { 390 t.Helper() 391 392 _, execErr := exec.LookPath("nmstatectl") 393 if execErr != nil { 394 t.Skip("No nmstatectl binary available") 395 } 396 }