diff --git a/pkg/types/gcp/validation/machinepool.go b/pkg/types/gcp/validation/machinepool.go index 39a244701a3..1d2d68ae17a 100644 --- a/pkg/types/gcp/validation/machinepool.go +++ b/pkg/types/gcp/validation/machinepool.go @@ -76,3 +76,30 @@ func ValidateDefaultDiskType(p *gcp.MachinePool, fldPath *field.Path) field.Erro return allErrs } + +// ValidateOSImageForSovereignCloud checks that an OS image is specified for sovereign cloud environments. +func ValidateOSImageForSovereignCloud(platform *gcp.Platform, pool *gcp.MachinePool, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + + if gcp.GetCloudEnvironment(platform.ProjectID) != gcp.CloudEnvironmentSovereign { + return allErrs + } + + if pool == nil || pool.OSImage == nil { + allErrs = append(allErrs, field.Required(fldPath.Child("osImage"), + "must specify an OS image for sovereign cloud environments (domain-scoped project ID)")) + return allErrs + } + + osImagePath := fldPath.Child("osImage") + if pool.OSImage.Name == "" { + allErrs = append(allErrs, field.Required(osImagePath.Child("name"), + "must specify an OS image name for sovereign cloud environments")) + } + if pool.OSImage.Project == "" { + allErrs = append(allErrs, field.Required(osImagePath.Child("project"), + "must specify an OS image project for sovereign cloud environments")) + } + + return allErrs +} diff --git a/pkg/types/gcp/validation/machinepool_test.go b/pkg/types/gcp/validation/machinepool_test.go index 2547429f0cf..399d8abba7c 100644 --- a/pkg/types/gcp/validation/machinepool_test.go +++ b/pkg/types/gcp/validation/machinepool_test.go @@ -9,6 +9,67 @@ import ( "github.com/openshift/installer/pkg/types/gcp" ) +func TestValidateOSImageForSovereignCloud(t *testing.T) { + validOSImage := &gcp.OSImage{Name: "my-image", Project: "my-project"} + + cases := []struct { + name string + platform *gcp.Platform + pool *gcp.MachinePool + expectedError string + }{ + { + name: "non-sovereign cloud skips validation", + platform: &gcp.Platform{ProjectID: "my-project"}, + pool: &gcp.MachinePool{}, + }, + { + name: "sovereign cloud with os image on pool", + platform: &gcp.Platform{ProjectID: "eu0:my-project"}, + pool: &gcp.MachinePool{OSImage: validOSImage}, + }, + { + name: "sovereign cloud missing os image on pool", + platform: &gcp.Platform{ProjectID: "eu0:my-project"}, + pool: &gcp.MachinePool{}, + expectedError: `test-path.osImage: Required value: must specify an OS image for sovereign cloud environments (domain-scoped project ID)`, + }, + { + name: "sovereign cloud nil pool", + platform: &gcp.Platform{ProjectID: "eu0:my-project"}, + pool: nil, + expectedError: `test-path.osImage: Required value: must specify an OS image for sovereign cloud environments (domain-scoped project ID)`, + }, + { + name: "sovereign cloud os image missing name", + platform: &gcp.Platform{ProjectID: "eu0:my-project"}, + pool: &gcp.MachinePool{OSImage: &gcp.OSImage{Project: "my-project"}}, + expectedError: `test-path.osImage.name: Required value: must specify an OS image name for sovereign cloud environments`, + }, + { + name: "sovereign cloud os image missing project", + platform: &gcp.Platform{ProjectID: "eu0:my-project"}, + pool: &gcp.MachinePool{OSImage: &gcp.OSImage{Name: "my-image"}}, + expectedError: `test-path.osImage.project: Required value: must specify an OS image project for sovereign cloud environments`, + }, + { + name: "org-scoped project ID is not sovereign", + platform: &gcp.Platform{ProjectID: "myorg:my-project"}, + pool: &gcp.MachinePool{}, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + err := ValidateOSImageForSovereignCloud(tc.platform, tc.pool, field.NewPath("test-path")).ToAggregate() + if tc.expectedError == "" { + assert.NoError(t, err) + } else { + assert.EqualError(t, err, tc.expectedError) + } + }) + } +} + func TestValidateMachinePool(t *testing.T) { platform := &gcp.Platform{Region: "us-east1"} cases := []struct { diff --git a/pkg/types/validation/machinepools.go b/pkg/types/validation/machinepools.go index 160e58a2d65..0e58627ef2d 100644 --- a/pkg/types/validation/machinepools.go +++ b/pkg/types/validation/machinepools.go @@ -162,6 +162,9 @@ func validateMachinePoolPlatform(platform *types.Platform, p *types.MachinePoolP return azurevalidation.ValidateMachinePool(p.Azure, pool.Name, platform.Azure, pool, f) }) } + if platform.GCP != nil { + allErrs = append(allErrs, gcpvalidation.ValidateOSImageForSovereignCloud(platform.GCP, p.GCP, fldPath.Child("gcp"))...) + } if p.GCP != nil { validate(gcp.Name, p.GCP, func(f *field.Path) field.ErrorList { return validateGCPMachinePool(platform, p, pool, f) }) }