Skip to content

Guest attributes data source #8556

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/12081.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-datasource
`google_compute_instance_guest_attributes`
```
1 change: 1 addition & 0 deletions google-beta/provider/provider_mmv1_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,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(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package compute

import (
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource"
transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport"
compute "google.golang.org/api/compute/v0.beta"
)

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
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package compute_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/acctest"
compute "google.golang.org/api/compute/v0.beta"
)

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)
}
74 changes: 74 additions & 0 deletions website/docs/d/compute_instance_guest_attributes.html.markdown
Original file line number Diff line number Diff line change
@@ -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.

---

<a name="nested_query_value"></a>The `query_value` block supports:

* `key` - Key of the guest_attribute.

* `namespace` - Namespace of the guest_attribute.

* `value` - Value of the guest_attribute.