diff --git a/mmv1/third_party/terraform/provider/provider_mmv1_resources.go.tmpl b/mmv1/third_party/terraform/provider/provider_mmv1_resources.go.tmpl index 2c3551c76fed..f51145ab32cf 100644 --- a/mmv1/third_party/terraform/provider/provider_mmv1_resources.go.tmpl +++ b/mmv1/third_party/terraform/provider/provider_mmv1_resources.go.tmpl @@ -86,6 +86,7 @@ var handwrittenDatasources = map[string]*schema.Resource{ "google_compute_instance_group_manager": compute.DataSourceGoogleComputeInstanceGroupManager(), "google_compute_instance_serial_port": compute.DataSourceGoogleComputeInstanceSerialPort(), "google_compute_instance_template": compute.DataSourceGoogleComputeInstanceTemplate(), + "google_compute_instance_guest_attributes": compute.DataSourceGoogleComputeInstanceGuestAttributes(), "google_compute_lb_ip_ranges": compute.DataSourceGoogleComputeLbIpRanges(), "google_compute_machine_types": compute.DataSourceGoogleComputeMachineTypes(), "google_compute_network": compute.DataSourceGoogleComputeNetwork(), diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_instance_guest_attributes.go.tmpl b/mmv1/third_party/terraform/services/compute/data_source_google_compute_instance_guest_attributes.go.tmpl new file mode 100644 index 000000000000..7f0bbcf2ff64 --- /dev/null +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_instance_guest_attributes.go.tmpl @@ -0,0 +1,135 @@ +package compute + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +{{- if ne $.TargetVersionName "ga" }} + compute "google.golang.org/api/compute/v0.beta" +{{- else }} + compute "google.golang.org/api/compute/v1" +{{- end }} +) + +func DataSourceGoogleComputeInstanceGuestAttributes() *schema.Resource { + return &schema.Resource{ + Read: dataSourceGoogleComputeInstanceGuestAttributesRead, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "region": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "zone": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "query_path": { + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"variable_key"}, + }, + + "variable_key": { + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"query_path"}, + }, + + "variable_value": { + Type: schema.TypeString, + Computed: true, + }, + + "query_value": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Computed: true, + }, + "namespace": { + Type: schema.TypeString, + Computed: true, + }, + "value": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func dataSourceGoogleComputeInstanceGuestAttributesRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + project, zone, name, err := tpgresource.GetZonalResourcePropertiesFromSelfLinkOrSchema(d, config) + if err != nil { + return err + } + + id := fmt.Sprintf("projects/%s/zones/%s/instances/%s", project, zone, name) + instanceGuestAttributes := &compute.GuestAttributes{} + + // You can either query based on variable_key, query_path or just get the first value + if d.Get("query_path").(string) != "" { + instanceGuestAttributes, err = config.NewComputeClient(userAgent).Instances.GetGuestAttributes(project, zone, name).QueryPath(d.Get("query_path").(string)).Do() + } else if d.Get("variable_key").(string) != "" { + instanceGuestAttributes, err = config.NewComputeClient(userAgent).Instances.GetGuestAttributes(project, zone, name).VariableKey(d.Get("variable_key").(string)).Do() + } else { + instanceGuestAttributes, err = config.NewComputeClient(userAgent).Instances.GetGuestAttributes(project, zone, name).Do() + } + if err != nil { + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Instance's Guest Attributes %s", name), id) + } + + // Set query results + if err := d.Set("variable_value", instanceGuestAttributes.VariableValue); err != nil { + return fmt.Errorf("Error variable_value: %s", err) + } + if err := d.Set("query_value", flattenQueryValues(instanceGuestAttributes.QueryValue)); err != nil { + return fmt.Errorf("Error query_value: %s", err) + } + + d.SetId(fmt.Sprintf(instanceGuestAttributes.SelfLink)) + return nil +} + +func flattenQueryValues(queryValue *compute.GuestAttributesValue) []map[string]interface{} { + if queryValue == nil { + return nil + } + queryValueItems := make([]map[string]interface{}, 0) + for _, item := range queryValue.Items { + queryValueItems = append(queryValueItems, map[string]interface{}{ + "key": item.Key, + "namespace": item.Namespace, + "value": item.Value, + }) + } + return queryValueItems +} diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_instance_guest_attributes_test.go.tmpl b/mmv1/third_party/terraform/services/compute/data_source_google_compute_instance_guest_attributes_test.go.tmpl new file mode 100644 index 000000000000..e23e665b6921 --- /dev/null +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_instance_guest_attributes_test.go.tmpl @@ -0,0 +1,157 @@ +package compute_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-google/google/acctest" + {{- if ne $.TargetVersionName "ga" }} + compute "google.golang.org/api/compute/v0.beta" +{{- else }} + compute "google.golang.org/api/compute/v1" +{{- end }} +) + +func TestAccDataSourceComputeInstanceGuestAttributes_basic(t *testing.T) { + t.Parallel() + + var instance compute.Instance + instanceName := fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10)) + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckComputeInstanceDestroyProducer(t), + Steps: []resource.TestStep{ + { + //need to create the guest_attributes metadata from startup script first + Config: testAccDataSourceComputeInstanceGuestAttributesInitialConfig(instanceName), + Check: testAccCheckComputeInstanceExists(t, "google_compute_instance.foo", &instance), + }, + { + Config: testAccDataSourceComputeInstanceGuestAttributesConfig_variableKey(instanceName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.google_compute_instance_guest_attributes.bar", "variable_key", "testing/key2"), + resource.TestCheckResourceAttr("data.google_compute_instance_guest_attributes.bar", "variable_value", "test2"), + ), + }, + { + Config: testAccDataSourceComputeInstanceGuestAttributesConfig_queryPath(instanceName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.google_compute_instance_guest_attributes.bar", "query_path", "testing/"), + resource.TestCheckResourceAttr("data.google_compute_instance_guest_attributes.bar", "query_value.0.value", "test1"), + resource.TestCheckResourceAttr("data.google_compute_instance_guest_attributes.bar", "query_value.1.value", "test2"), + ), + }, + }, + }) +} + +func testAccDataSourceComputeInstanceGuestAttributesInitialConfig(instanceName string) string { + return fmt.Sprintf(` +resource "google_compute_instance" "foo" { + name = "%s" + machine_type = "n1-standard-1" + zone = "us-central1-a" + + boot_disk { + initialize_params { + image = "debian-8-jessie-v20160803" + } + } + + network_interface { + network = "default" + access_config { + // Ephemeral IP + } + } + + metadata = { + enable-guest-attributes = "TRUE" + } + + metadata_startup_script = <<-EOF + curl -X PUT --data "test1" http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/testing/key1 -H "Metadata-Flavor: Google" + curl -X PUT --data "test2" http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/testing/key2 -H "Metadata-Flavor: Google" + EOF +} +`, instanceName) +} + +func testAccDataSourceComputeInstanceGuestAttributesConfig_queryPath(instanceName string) string { + return fmt.Sprintf(` +resource "google_compute_instance" "foo" { + name = "%s" + machine_type = "n1-standard-1" + zone = "us-central1-a" + + boot_disk { + initialize_params { + image = "debian-8-jessie-v20160803" + } + } + + network_interface { + network = "default" + access_config { + // Ephemeral IP + } + } + + metadata = { + enable-guest-attributes = "TRUE" + } + + metadata_startup_script = <<-EOF + curl -X PUT --data "test1" http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/testing/key1 -H "Metadata-Flavor: Google" + curl -X PUT --data "test2" http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/testing/key2 -H "Metadata-Flavor: Google" + EOF +} + +data "google_compute_instance_guest_attributes" "bar" { + name = google_compute_instance.foo.name + zone = "us-central1-a" + query_path = "testing/" +} +`, instanceName) +} + +func testAccDataSourceComputeInstanceGuestAttributesConfig_variableKey(instanceName string) string { + return fmt.Sprintf(` +resource "google_compute_instance" "foo" { + name = "%s" + machine_type = "n1-standard-1" + zone = "us-central1-a" + + boot_disk { + initialize_params { + image = "debian-8-jessie-v20160803" + } + } + + network_interface { + network = "default" + access_config { + // Ephemeral IP + } + } + + metadata = { + enable-guest-attributes = "TRUE" + } + + metadata_startup_script = <<-EOF + curl -X PUT --data "test1" http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/testing/key1 -H "Metadata-Flavor: Google" + curl -X PUT --data "test2" http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/testing/key2 -H "Metadata-Flavor: Google" + EOF +} + +data "google_compute_instance_guest_attributes" "bar" { + name = google_compute_instance.foo.name + zone = "us-central1-a" + variable_key = "testing/key2" +} +`, instanceName) +} diff --git a/mmv1/third_party/terraform/website/docs/d/compute_instance_guest_attributes.html.markdown b/mmv1/third_party/terraform/website/docs/d/compute_instance_guest_attributes.html.markdown new file mode 100644 index 000000000000..f85f9deecf47 --- /dev/null +++ b/mmv1/third_party/terraform/website/docs/d/compute_instance_guest_attributes.html.markdown @@ -0,0 +1,74 @@ +--- +subcategory: "Compute Engine" +description: |- + Get GCE instance's guest attributes +--- + +# google_compute_instance_guest_attributes + +Get information about a VM instance resource within GCE. For more information see +[the official documentation](https://cloud.google.com/compute/docs/instances) +and +[API](https://cloud.google.com/compute/docs/reference/latest/instances). + +Get information about VM's guest attrubutes. For more information see [the official documentation](https://cloud.google.com/compute/docs/metadata/manage-guest-attributes) +and +[API](https://cloud.google.com/compute/docs/reference/rest/v1/instances/getGuestAttributes). + +## Example Usage - get all attributes from a single namespace + +```hcl +data "google_compute_instance_guest_attributes" "appserver_ga" { + name = "primary-application-server" + zone = "us-central1-a" + query_path = "variables/" +} +``` + +## Example Usage - get a specific variable + +```hcl +data "google_compute_instance_guest_attributes" "appserver_ga" { + name = "primary-application-server" + zone = "us-central1-a" + variable_key = "variables/key1" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Optional) The name or self_link of the instance. + +--- + +* `project` - (Optional) The ID of the project in which the resource belongs. + If `self_link` is provided, this value is ignored. If neither `self_link` + nor `project` are provided, the provider project is used. + +* `zone` - (Optional) The zone of the instance. If `self_link` is provided, this + value is ignored. If neither `self_link` nor `zone` are provided, the + provider zone is used. + +* `query_path` - (Optional) Path to query for the guest attributes. Consists of + `namespace` name for the attributes followed with a `/`. + +* `variable_key` - (Optional) Key of a variable to get the value of. Consists of + `namespace` name and `key` name for the variable separated by a `/`. + +## Attributes Reference + +* `query_value` - Structure is [documented below](#nested_query_value). + +* `variable_value` - Value of the queried guest_attribute. + +--- + +The `query_value` block supports: + +* `key` - Key of the guest_attribute. + +* `namespace` - Namespace of the guest_attribute. + +* `value` - Value of the guest_attribute. \ No newline at end of file