Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
a7cbdac
Migrate PT. 5 of compute_instance_helpers.go.tmpl to new API
inadenenko Jun 17, 2026
1171d0e
fix build
inadenenko Jun 17, 2026
0806c16
guard strconv
inadenenko Jun 17, 2026
513b066
fix build
inadenenko Jun 17, 2026
22537fb
fix convertion
inadenenko Jun 17, 2026
2f5e29d
fix tests panic
inadenenko Jun 17, 2026
b53d75f
update changes to resource_compute_instance
inadenenko Jun 17, 2026
66ef5aa
other PRs merge
inadenenko Jun 18, 2026
e95b27c
fix imports
inadenenko Jun 18, 2026
b6083cc
vcr fixes
inadenenko Jun 18, 2026
5e2fa2a
more test fixes
inadenenko Jun 18, 2026
c6ac443
tests fix
inadenenko Jun 19, 2026
206bfe6
rebase
inadenenko Jun 25, 2026
a75e167
Migrate `expandAdvancedMachineFeatures`, `flattenAdvancedMachineFeatu…
nsamartsev May 25, 2026
3db2d11
fetch other branch changes
inadenenko Jun 25, 2026
9b01220
fix
inadenenko Jun 25, 2026
0b2a751
fmt
inadenenko Jun 29, 2026
1926776
Migrate metadata files to new API
inadenenko Jun 29, 2026
ea30bc5
remove remaining compute
inadenenko Jun 29, 2026
58ccd56
err undefined fix
inadenenko Jun 29, 2026
a2dd03f
tfplan2cai fix
inadenenko Jun 29, 2026
353418c
fix
inadenenko Jun 29, 2026
53acea9
fix panic in tests
inadenenko Jun 29, 2026
5185d83
add condition for json import
inadenenko Jun 29, 2026
6c411d4
vcr tests fix
inadenenko Jun 29, 2026
14f3ec4
fix
inadenenko Jun 29, 2026
3c1d26c
fix
inadenenko Jun 29, 2026
efb1b7f
VCR tests + json.Marshal fixes
inadenenko Jun 30, 2026
68c569f
remove excess len clause
inadenenko Jun 30, 2026
b7cb180
fix instance from machine image
inadenenko Jun 30, 2026
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

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,13 @@ func dataSourceGoogleComputeInstanceRead(d *schema.ResourceData, meta interface{
return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Instance %s", name), id)
}

md := flattenMetadataBeta(instance.Metadata)
var metadataMap map[string]interface{}
if instance.Metadata != nil {
if metadataMap, err = tpgresource.ConvertToMap(instance.Metadata); err != nil {
return fmt.Errorf("error converting metadata: %s", err)
}
}
md := flattenMetadataBeta(metadataMap)
if err = d.Set("metadata", md); err != nil {
return fmt.Errorf("error setting metadata: %s", err)
}
Expand Down Expand Up @@ -152,7 +158,11 @@ func dataSourceGoogleComputeInstanceRead(d *schema.ResourceData, meta interface{
return err
}

err = d.Set("scheduling", flattenScheduling(instance.Scheduling))
schedulingMap, err := tpgresource.ConvertToMap(instance.Scheduling)
if err != nil {
return fmt.Errorf("Error converting scheduling: %s", err)
}
err = d.Set("scheduling", flattenScheduling(schedulingMap))
if err != nil {
return err
}
Expand Down
112 changes: 34 additions & 78 deletions mmv1/third_party/terraform/services/compute/metadata.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ import (
{{- end }}
"sort"

{{ if eq $.TargetVersionName `ga` }}
"google.golang.org/api/compute/v1"
{{- else }}
compute "google.golang.org/api/compute/v0.beta"
{{- end }}

"github.com/hashicorp/terraform-provider-google/google/tpgresource"
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
)
Expand Down Expand Up @@ -50,71 +44,69 @@ func BetaMetadataUpdate(oldMDMap map[string]interface{}, newMDMap map[string]int
MetadataUpdate(oldMDMap, newMDMap, serverMD)
}

func expandComputeMetadata(m map[string]interface{}) []*compute.MetadataItems {
metadata := make([]*compute.MetadataItems, 0, len(m))
func expandComputeMetadata(m map[string]interface{}) []interface{} {
metadata := make([]interface{}, 0, len(m))
var keys []string
for key := range m {
keys = append(keys, key)
}
sort.Strings(keys)
// Append new metadata to existing metadata
for _, key := range keys {
v := m[key].(string)
metadata = append(metadata, &compute.MetadataItems{
Key: key,
Value: &v,
metadata = append(metadata, map[string]interface{}{
"key": key,
"value": v,
})
}

return metadata
}

func flattenMetadataBeta(metadata *compute.Metadata) map[string]string {
func flattenMetadataBeta(metadata map[string]interface{}) map[string]string {
metadataMap := make(map[string]string)
if metadata == nil {
return metadataMap
}
for _, item := range metadata.Items {
if item == nil {
items, _ := metadata["items"].([]interface{})
for _, raw := range items {
item, ok := raw.(map[string]interface{})
if !ok || item == nil {
continue
}
if item.Value == nil {
metadataMap[item.Key] = ""
} else {
metadataMap[item.Key] = *item.Value
key, _ := item["key"].(string)
if key == "" {
continue
}
val, _ := item["value"].(string)
metadataMap[key] = val
}
return metadataMap
}

// This function differs from flattenMetadataBeta only in that it takes
// compute.metadata rather than compute.metadata as an argument. It should
// be removed in favour of flattenMetadataBeta if/when all resources using it get
// beta support.
func FlattenMetadata(metadata *compute.Metadata) map[string]interface{} {
func FlattenMetadata(metadata map[string]interface{}) map[string]interface{} {
metadataMap := make(map[string]interface{})
if metadata == nil {
return metadataMap
}
for _, item := range metadata.Items {
if item == nil {
items, _ := metadata["items"].([]interface{})
for _, raw := range items {
item, ok := raw.(map[string]interface{})
if !ok || item == nil {
continue
}
if item.Value == nil {
metadataMap[item.Key] = ""
} else {
metadataMap[item.Key] = *item.Value
key, _ := item["key"].(string)
if key == "" {
continue
}
val, _ := item["value"].(string)
metadataMap[key] = val
}
return metadataMap
}

// resourceInstanceMetadata builds the instance metadata as a JSON-shaped
// map[string]interface{} mirroring the compute.Metadata API type (camelCase
// keys: "items" -> [{"key", "value"}], "fingerprint"). Empty values are omitted
// to mirror the Apiary struct's omitempty tags, so the marshaled request body is
// byte-identical whether the map is sent directly or round-tripped through the
// typed struct via resourceInstanceMetadataTyped.
// to mirror the Apiary struct's omitempty tags.
func resourceInstanceMetadata(d tpgresource.TerraformResourceData) (map[string]interface{}, error) {
m := map[string]interface{}{}
mdMap := d.Get("metadata").(map[string]interface{})
Expand Down Expand Up @@ -154,20 +146,6 @@ func resourceInstanceMetadata(d tpgresource.TerraformResourceData) (map[string]i
return m, nil
}

// resourceInstanceMetadataTyped adapts the map-based resourceInstanceMetadata
// output to the typed *compute.Metadata still required by callers that build
// Apiary request structs directly.
func resourceInstanceMetadataTyped(d tpgresource.TerraformResourceData) (*compute.Metadata, error) {
mdMap, err := resourceInstanceMetadata(d)
if err != nil {
return nil, err
}
m := &compute.Metadata{}
if err := convertViaJSON(mdMap, m); err != nil {
return nil, err
}
return m, nil
}
{{- if ne $.TargetVersionName "ga" }}

func resourceInstancePartnerMetadata(d tpgresource.TerraformResourceData) (map[string]interface{}, error) {
Expand Down Expand Up @@ -210,9 +188,7 @@ func flattenPartnerMetadata(partnerMetadata map[string]interface{}) (map[string]

// convertPartnerMetadataToCompute builds the partner metadata as a JSON-shaped
// map[string]interface{} mirroring the compute.StructuredEntries API type (each
// value is the parsed entries object, or an empty object for nil). The typed
// adapter convertPartnerMetadataToComputeTyped round-trips this through
// map[string]compute.StructuredEntries for callers that build Apiary structs.
// value is the parsed entries object, or an empty object for nil).
func convertPartnerMetadataToCompute(pm map[string]interface{}) (map[string]interface{}, error) {
result := make(map[string]interface{})
for key, value := range pm {
Expand All @@ -225,40 +201,20 @@ func convertPartnerMetadataToCompute(pm map[string]interface{}) (map[string]inte
return result, nil
}

// convertPartnerMetadataToComputeTyped adapts the map-based
// convertPartnerMetadataToCompute output to the typed
// map[string]compute.StructuredEntries still required by callers that build
// Apiary request structs directly.
func convertPartnerMetadataToComputeTyped(pm map[string]interface{}) (map[string]compute.StructuredEntries, error) {
pmMap, err := convertPartnerMetadataToCompute(pm)
if err != nil {
return nil, err
}
result := make(map[string]compute.StructuredEntries)
if err := convertViaJSON(pmMap, &result); err != nil {
return nil, err
}
return result, nil
}

func convertPartnerMetadataFromCompute(pm map[string]compute.StructuredEntries) map[string]interface{} {
func convertPartnerMetadataFromCompute(pm map[string]interface{}) map[string]interface{} {
result := make(map[string]interface{})
for key, value := range pm {
if value.Entries == nil {
for key, raw := range pm {
value, ok := raw.(map[string]interface{})
if !ok || value == nil {
result[key] = nil
continue
}
seBytes, err := json.Marshal(value)
if err != nil {
entries, hasEntries := value["entries"]
if !hasEntries || entries == nil {
result[key] = nil
continue
}
var m map[string]interface{}
if err := json.Unmarshal(seBytes, &m); err != nil {
result[key] = nil
continue
}
result[key] = m
result[key] = value
}
return result
}
Expand Down
Loading
Loading