diff --git a/mmv1/third_party/terraform/acctest/provider_test_utils.go b/mmv1/third_party/terraform/acctest/provider_test_utils.go index 81bc0fd80a1d..0a13f0206aa1 100644 --- a/mmv1/third_party/terraform/acctest/provider_test_utils.go +++ b/mmv1/third_party/terraform/acctest/provider_test_utils.go @@ -40,6 +40,14 @@ func GoogleProviderConfig(t *testing.T) *transport_tpg.Config { sdkProvider := provider.Provider() rc := terraform.ResourceConfig{} + + // `universe_domain` must be specified through config (i.e. unlike most provider settings there's no environment variable), and we check the value matches the credentials during provider initilization + // In the test environment we seed the value through a test-only environment variable, and we need to pre-seed a value in ResourceConfig as if it was in config to pass the check + universeDomain := envvar.GetTestUniverseDomainFromEnv(t) + if universeDomain != "" && universeDomain != "googleapis.com" { + rc.Config = make(map[string]interface{}) + rc.Config["universe_domain"] = universeDomain + } sdkProvider.Configure(context.Background(), &rc) return sdkProvider.Meta().(*transport_tpg.Config) } diff --git a/mmv1/third_party/terraform/envvar/envvar_utils.go b/mmv1/third_party/terraform/envvar/envvar_utils.go index 537242cef5e9..dbd6b4707167 100644 --- a/mmv1/third_party/terraform/envvar/envvar_utils.go +++ b/mmv1/third_party/terraform/envvar/envvar_utils.go @@ -86,6 +86,10 @@ var UniverseDomainEnvVars = []string{ "GOOGLE_UNIVERSE_DOMAIN", } +var ProjectPrefixEnvVars = []string{ + "GOOGLE_PROJECT_PREFIX", +} + // This is the billing account that will be charged for the infrastructure used during testing. For // that reason, it is also the billing account used for creating new projects. var BillingAccountEnvVars = []string{ @@ -146,6 +150,11 @@ func GetTestUniverseDomainFromEnv(t *testing.T) string { return transport_tpg.MultiEnvSearch(UniverseDomainEnvVars) } +// Project Prefix of different universes +func GetProjectPrefixFromEnv() string { + return transport_tpg.MultiEnvSearch(ProjectPrefixEnvVars) +} + // AccTestPreCheck ensures at least one of the region env variables is set. func GetTestRegionFromEnv() string { return transport_tpg.MultiEnvSearch(RegionEnvVars) diff --git a/mmv1/third_party/terraform/provider/provider.go.tmpl b/mmv1/third_party/terraform/provider/provider.go.tmpl index d4f6bf90270b..76f0eb3f7246 100644 --- a/mmv1/third_party/terraform/provider/provider.go.tmpl +++ b/mmv1/third_party/terraform/provider/provider.go.tmpl @@ -426,7 +426,6 @@ func ProviderConfigure(ctx context.Context, d *schema.ResourceData, p *schema.Pr if err := config.LoadAndValidate(stopCtx); err != nil { return nil, diag.FromErr(err) } - // Verify that universe domains match between credentials and configuration if v, ok := d.GetOk("universe_domain"); ok { if config.UniverseDomain == "" && v.(string) != "googleapis.com" { // v can't be "", as it wouldn't pass `ok` above diff --git a/mmv1/third_party/terraform/provider/universe/universe_domain_compute_test.go b/mmv1/third_party/terraform/provider/universe/universe_domain_compute_test.go index ea2703508e3b..89d1d5d39bcd 100644 --- a/mmv1/third_party/terraform/provider/universe/universe_domain_compute_test.go +++ b/mmv1/third_party/terraform/provider/universe/universe_domain_compute_test.go @@ -33,6 +33,31 @@ func TestAccUniverseDomainDisk(t *testing.T) { }) } +func TestAccUniverseDomainDiskImage(t *testing.T) { + + universeDomain := envvar.GetTestUniverseDomainFromEnv(t) + zone := envvar.GetTestZoneFromEnv() + prefix := envvar.GetProjectPrefixFromEnv() + image_project := "" + + if prefix != "" { + image_project = prefix + ":debian-cloud" + } else { + image_project = "debian-cloud" + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckComputeDiskDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccUniverseDomain_basic_disk_image(universeDomain, zone, image_project), + }, + }, + }) +} + func TestAccDefaultUniverseDomainDisk(t *testing.T) { universeDomain := "googleapis.com" @@ -85,6 +110,28 @@ resource "google_compute_instance_template" "instance_template" { `, universeDomain) } +func testAccUniverseDomain_basic_disk_image(universeDomain, zone, image_project string) string { + return fmt.Sprintf(` +provider "google" { + universe_domain = "%s" +} + +data "google_compute_images" "debian" { + project = "%s" + filter = "name=debian-12*" +} + +resource "google_compute_disk" "primary" { + name = "async-test-disk" + type = "pd-ssd" + zone = "%s" + + physical_block_size_bytes = 4096 + image = "projects/%s/global/images/${data.google_compute_images.debian.images[0].name}" +} +`, universeDomain, image_project, zone, image_project) +} + func testAccCheckComputeDiskDestroyProducer(t *testing.T) func(s *terraform.State) error { return func(s *terraform.State) error { for name, rs := range s.RootModule().Resources { diff --git a/mmv1/third_party/terraform/services/compute/image.go b/mmv1/third_party/terraform/services/compute/image.go index e35942046e24..bc72330267f6 100644 --- a/mmv1/third_party/terraform/services/compute/image.go +++ b/mmv1/third_party/terraform/services/compute/image.go @@ -106,6 +106,9 @@ func ResolveImage(c *transport_tpg.Config, project, name, userAgent string) (str break } } + if c.UniverseDomain != "" && c.UniverseDomain != "googleapis.com" { + resolveImageLink = regexp.MustCompile(fmt.Sprintf("^https://compute.%s/compute/[a-z0-9]+/projects/(%s)/global/images/(%s)", c.UniverseDomain, verify.ProjectRegex, resolveImageImageRegex)) + } switch { case resolveImageLink.MatchString(name): // https://www.googleapis.com/compute/v1/projects/xyz/global/images/xyz return name, nil