-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3f906b3
commit b84ed5f
Showing
3 changed files
with
462 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
package google | ||
|
||
import ( | ||
"fmt" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func dataSourceGoogleComputeInstance() *schema.Resource { | ||
// Generate datasource schema from resource | ||
dsSchema := datasourceSchemaFromResourceSchema(resourceComputeInstance().Schema) | ||
|
||
// Set 'Required' schema elements | ||
addRequiredFieldsToSchema(dsSchema, "name") | ||
|
||
// Set 'Optional' schema elements | ||
addOptionalFieldsToSchema(dsSchema, "project", "zone") | ||
|
||
return &schema.Resource{ | ||
Read: dataSourceGoogleComputeInstanceRead, | ||
Schema: dsSchema, | ||
} | ||
} | ||
|
||
func dataSourceGoogleComputeInstanceRead(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
project, err := getProject(d, config) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
zone, err := getZone(d, config) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
name := d.Get("name").(string) | ||
|
||
instance, err := config.clientComputeBeta.Instances.Get(project, zone, name).Do() | ||
if err != nil { | ||
return handleNotFoundError(err, d, fmt.Sprintf("Instance %s", name)) | ||
} | ||
|
||
md := flattenMetadataBeta(instance.Metadata) | ||
if err = d.Set("metadata", md); err != nil { | ||
return fmt.Errorf("error setting metadata: %s", err) | ||
} | ||
|
||
d.Set("can_ip_forward", instance.CanIpForward) | ||
d.Set("machine_type", GetResourceNameFromSelfLink(instance.MachineType)) | ||
|
||
// Set the networks | ||
// Use the first external IP found for the default connection info. | ||
networkInterfaces, _, internalIP, externalIP, err := flattenNetworkInterfaces(d, config, instance.NetworkInterfaces) | ||
if err != nil { | ||
return err | ||
} | ||
if err := d.Set("network_interface", networkInterfaces); err != nil { | ||
return err | ||
} | ||
|
||
// Fall back on internal ip if there is no external ip. This makes sense in the situation where | ||
// terraform is being used on a cloud instance and can therefore access the instances it creates | ||
// via their internal ips. | ||
sshIP := externalIP | ||
if sshIP == "" { | ||
sshIP = internalIP | ||
} | ||
|
||
// Initialize the connection info | ||
d.SetConnInfo(map[string]string{ | ||
"type": "ssh", | ||
"host": sshIP, | ||
}) | ||
|
||
// Set the metadata fingerprint if there is one. | ||
if instance.Metadata != nil { | ||
d.Set("metadata_fingerprint", instance.Metadata.Fingerprint) | ||
} | ||
|
||
// Set the tags fingerprint if there is one. | ||
if instance.Tags != nil { | ||
d.Set("tags_fingerprint", instance.Tags.Fingerprint) | ||
d.Set("tags", convertStringArrToInterface(instance.Tags.Items)) | ||
} | ||
|
||
if err := d.Set("labels", instance.Labels); err != nil { | ||
return err | ||
} | ||
|
||
if instance.LabelFingerprint != "" { | ||
d.Set("label_fingerprint", instance.LabelFingerprint) | ||
} | ||
|
||
attachedDisks := []map[string]interface{}{} | ||
scratchDisks := []map[string]interface{}{} | ||
for _, disk := range instance.Disks { | ||
if disk.Boot { | ||
d.Set("boot_disk", flattenBootDisk(d, disk, config)) | ||
} else if disk.Type == "SCRATCH" { | ||
scratchDisks = append(scratchDisks, flattenScratchDisk(disk)) | ||
} else { | ||
di := map[string]interface{}{ | ||
"source": ConvertSelfLinkToV1(disk.Source), | ||
"device_name": disk.DeviceName, | ||
"mode": disk.Mode, | ||
} | ||
if key := disk.DiskEncryptionKey; key != nil { | ||
di["disk_encryption_key_sha256"] = key.Sha256 | ||
} | ||
attachedDisks = append(attachedDisks, di) | ||
} | ||
} | ||
// Remove nils from map in case there were disks in the config that were not present on read; | ||
// i.e. a disk was detached out of band | ||
ads := []map[string]interface{}{} | ||
for _, d := range attachedDisks { | ||
if d != nil { | ||
ads = append(ads, d) | ||
} | ||
} | ||
|
||
d.Set("service_account", flattenServiceAccounts(instance.ServiceAccounts)) | ||
d.Set("attached_disk", ads) | ||
d.Set("scratch_disk", scratchDisks) | ||
d.Set("scheduling", flattenScheduling(instance.Scheduling)) | ||
d.Set("guest_accelerator", flattenGuestAccelerators(instance.GuestAccelerators)) | ||
d.Set("cpu_platform", instance.CpuPlatform) | ||
d.Set("min_cpu_platform", instance.MinCpuPlatform) | ||
d.Set("deletion_protection", instance.DeletionProtection) | ||
d.Set("self_link", ConvertSelfLinkToV1(instance.SelfLink)) | ||
d.Set("instance_id", fmt.Sprintf("%d", instance.Id)) | ||
d.Set("project", project) | ||
d.Set("zone", GetResourceNameFromSelfLink(instance.Zone)) | ||
d.Set("name", instance.Name) | ||
|
||
d.SetId(instance.Name) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
package google | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/acctest" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func TestAccDataSourceComputeInstance_basic(t *testing.T) { | ||
t.Parallel() | ||
|
||
instanceName := fmt.Sprintf("data-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: testAccDataSourceComputeInstanceConfig(instanceName), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccDataSourceComputeInstanceCheck("data.google_compute_instance.bar", "google_compute_instance.foo"), | ||
resource.TestCheckResourceAttr("data.google_compute_instance.bar", "network_interface.#", "1"), | ||
resource.TestCheckResourceAttr("data.google_compute_instance.bar", "boot_disk.0.initialize_params.0.size", "10"), | ||
resource.TestCheckResourceAttr("data.google_compute_instance.bar", "boot_disk.0.initialize_params.0.type", "pd-standard"), | ||
resource.TestCheckResourceAttr("data.google_compute_instance.bar", "scratch_disk.0.interface", "SCSI"), | ||
resource.TestCheckResourceAttr("data.google_compute_instance.bar", "network_interface.0.access_config.0.network_tier", "PREMIUM"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccDataSourceComputeInstanceCheck(datasourceName string, resourceName string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
ds, ok := s.RootModule().Resources[datasourceName] | ||
if !ok { | ||
return fmt.Errorf("root module has no resource called %s", datasourceName) | ||
} | ||
|
||
rs, ok := s.RootModule().Resources[resourceName] | ||
if !ok { | ||
return fmt.Errorf("can't find %s in state", resourceName) | ||
} | ||
|
||
datasourceAttributes := ds.Primary.Attributes | ||
resourceAttributes := rs.Primary.Attributes | ||
|
||
instanceAttrsToTest := []string{ | ||
"name", | ||
"machine_type", | ||
"can_ip_forward", | ||
"description", | ||
"deletion_protection", | ||
"labels", | ||
"metadata", | ||
"min_cpu_platform", | ||
"project", | ||
"tags", | ||
"zone", | ||
"cpu_platform", | ||
"instance_id", | ||
"label_fingerprint", | ||
"metadata_fingerprint", | ||
"self_link", | ||
"tags_fingerprint", | ||
} | ||
|
||
for _, attrToCheck := range instanceAttrsToTest { | ||
if datasourceAttributes[attrToCheck] != resourceAttributes[attrToCheck] { | ||
return fmt.Errorf( | ||
"%s is %s; want %s", | ||
attrToCheck, | ||
datasourceAttributes[attrToCheck], | ||
resourceAttributes[attrToCheck], | ||
) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testAccDataSourceComputeInstanceConfig(instanceName string) string { | ||
return fmt.Sprintf(` | ||
resource "google_compute_instance" "foo" { | ||
name = "%s" | ||
machine_type = "n1-standard-1" | ||
zone = "us-central1-a" | ||
can_ip_forward = false | ||
tags = ["foo", "bar"] | ||
boot_disk { | ||
initialize_params{ | ||
image = "debian-8-jessie-v20160803" | ||
} | ||
} | ||
scratch_disk { | ||
} | ||
network_interface { | ||
network = "default" | ||
access_config { | ||
// Ephemeral IP | ||
} | ||
} | ||
metadata { | ||
foo = "bar" | ||
baz = "qux" | ||
} | ||
create_timeout = 5 | ||
metadata { | ||
startup-script = "echo Hello" | ||
} | ||
labels { | ||
my_key = "my_value" | ||
my_other_key = "my_other_value" | ||
} | ||
} | ||
data "google_compute_instance" "bar" { | ||
name = "${google_compute_instance.foo.name}" | ||
zone = "us-central1-a" | ||
} | ||
`, instanceName) | ||
} |
Oops, something went wrong.