diff --git a/image.go b/image.go index 642b74d9..5a006eb9 100644 --- a/image.go +++ b/image.go @@ -6,8 +6,10 @@ import ( ) // If the given name is a URL, return it. -// If it is of the form project/name, use that URL. -// If it is of the form name then look in the configured project and then hosted image projects. +// If it is of the form project/name, search the specified project first, then +// search image families in the specified project. +// If it is of the form name then look in the configured project, then hosted +// image projects, and lastly at image families in hosted image projects. func resolveImage(c *Config, name string) (string, error) { if strings.HasPrefix(name, "https://www.googleapis.com/compute/v1/") { @@ -28,8 +30,8 @@ func resolveImage(c *Config, name string) (string, error) { // If we match a lookup for an alternate project, then try that next. // If not, we return the original error. - // If the image name contains the left hand side, we use the project from the right hand - // side. + // If the image name contains the left hand side, we use the project from + // the right hand side. imageMap := map[string]string{ "centos": "centos-cloud", "coreos": "coreos-cloud", @@ -57,13 +59,28 @@ func resolveImage(c *Config, name string) (string, error) { return image.SelfLink, nil } + // If it doesn't exist, try to see if it works as an image family: + image, err = c.clientCompute.Images.GetFromFamily(project, name).Do() + if err == nil { + return image.SelfLink, nil + } + return "", err } else if len(splitName) == 2 { + + // Check if image exists in the specified project: image, err := c.clientCompute.Images.Get(splitName[0], splitName[1]).Do() if err == nil { return image.SelfLink, nil } + + // If it doesn't, check if it exists as an image family: + image, err = c.clientCompute.Images.GetFromFamily(splitName[0], splitName[1]).Do() + if err == nil { + return image.SelfLink, nil + } + return "", err } else { diff --git a/resource_compute_instance_test.go b/resource_compute_instance_test.go index a20e127e..bdd8c3d3 100644 --- a/resource_compute_instance_test.go +++ b/resource_compute_instance_test.go @@ -104,6 +104,52 @@ func TestAccComputeInstance_basic3(t *testing.T) { }) } +func TestAccComputeInstance_basic4(t *testing.T) { + var instance compute.Instance + var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeInstanceDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeInstance_basic4(instanceName), + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeInstanceExists( + "google_compute_instance.foobar", &instance), + testAccCheckComputeInstanceTag(&instance, "foo"), + testAccCheckComputeInstanceMetadata(&instance, "foo", "bar"), + testAccCheckComputeInstanceDisk(&instance, instanceName, true, true), + ), + }, + }, + }) +} + +func TestAccComputeInstance_basic5(t *testing.T) { + var instance compute.Instance + var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeInstanceDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeInstance_basic5(instanceName), + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeInstanceExists( + "google_compute_instance.foobar", &instance), + testAccCheckComputeInstanceTag(&instance, "foo"), + testAccCheckComputeInstanceMetadata(&instance, "foo", "bar"), + testAccCheckComputeInstanceDisk(&instance, instanceName, true, true), + ), + }, + }, + }) +} + func TestAccComputeInstance_IP(t *testing.T) { var instance compute.Instance var ipName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) @@ -665,6 +711,29 @@ func testAccComputeInstance_basic(instance string) string { } func testAccComputeInstance_basic2(instance string) string { + return fmt.Sprintf(` + resource "google_compute_instance" "foobar" { + name = "%s" + machine_type = "n1-standard-1" + zone = "us-central1-a" + can_ip_forward = false + tags = ["foo", "bar"] + + disk { + image = "debian-8" + } + + network_interface { + network = "default" + } + + metadata { + foo = "bar" + } + }`, instance) +} + +func testAccComputeInstance_basic3(instance string) string { return fmt.Sprintf(` resource "google_compute_instance" "foobar" { name = "%s" @@ -688,7 +757,31 @@ func testAccComputeInstance_basic2(instance string) string { }`, instance) } -func testAccComputeInstance_basic3(instance string) string { +func testAccComputeInstance_basic4(instance string) string { + return fmt.Sprintf(` + resource "google_compute_instance" "foobar" { + name = "%s" + machine_type = "n1-standard-1" + zone = "us-central1-a" + can_ip_forward = false + tags = ["foo", "bar"] + + disk { + image = "debian-cloud/debian-8" + } + + network_interface { + network = "default" + } + + + metadata { + foo = "bar" + } + }`, instance) +} + +func testAccComputeInstance_basic5(instance string) string { return fmt.Sprintf(` resource "google_compute_instance" "foobar" { name = "%s"