terraform-provider-google/google/api_versions.go
Riley Karson 232cb87c7a Add versioned Beta support to google_compute_instance_group_manager (#234)
* Vendor GCP Compute Beta client library.

* Refactor resource_compute_instance_group_manager for multi version support (#129)

* Refactor resource_compute_instance_group_manager for multi version support.
* Minor changes based on review.
* Removed type-specific API version conversion functions.

* Add support for Beta operations.

* Add v0beta support to google_compute_instance_group_manager.

* Renamed Key to Feature, added comments & updated some parameter names.

* Fix code and tests for version finder to match fields that don't have a change.

* Store non-v1 resources' self links as v1 so that dependent single-version resources don't see diffs.

* Fix weird change to vendor.json from merge.

* Add a note that Convert loses ForceSendFields, fix failing test.

* Moved nil type to a switch case in compute_shared_operation.go.

* Move base api version declaration above schema.
2017-07-26 13:37:59 -07:00

101 lines
3.0 KiB
Go

package google
import (
"encoding/json"
)
type ComputeApiVersion uint8
const (
v1 ComputeApiVersion = iota
v0beta
)
var OrderedComputeApiVersions = []ComputeApiVersion{
v0beta,
v1,
}
// Convert between two types by converting to/from JSON. Intended to switch
// between multiple API versions, as they are strict supersets of one another.
// Convert loses information about ForceSendFields and NullFields.
func Convert(item, out interface{}) error {
bytes, err := json.Marshal(item)
if err != nil {
return err
}
err = json.Unmarshal(bytes, out)
if err != nil {
return err
}
return nil
}
type TerraformResourceData interface {
HasChange(string) bool
GetOk(string) (interface{}, bool)
}
// Compare the fields set in schema against a list of features and their versions to determine
// what version of the API is required in order to manage the resource.
func getComputeApiVersion(d TerraformResourceData, resourceVersion ComputeApiVersion, features []Feature) ComputeApiVersion {
versions := map[ComputeApiVersion]struct{}{resourceVersion: struct{}{}}
for _, feature := range features {
if feature.InUseBy(d) {
versions[feature.Version] = struct{}{}
}
}
return maxVersion(versions)
}
// Compare the fields set in schema against a list of features and their version, and a
// list of features that exist at the base resource version that can only be update at some other
// version, to determine what version of the API is required in order to update the resource.
func getComputeApiVersionUpdate(d TerraformResourceData, resourceVersion ComputeApiVersion, features, updateOnlyFields []Feature) ComputeApiVersion {
versions := map[ComputeApiVersion]struct{}{resourceVersion: struct{}{}}
schemaVersion := getComputeApiVersion(d, resourceVersion, features)
versions[schemaVersion] = struct{}{}
for _, feature := range updateOnlyFields {
if feature.HasChangeBy(d) {
versions[feature.Version] = struct{}{}
}
}
return maxVersion(versions)
}
// A field of a resource and the version of the Compute API required to use it.
type Feature struct {
Version ComputeApiVersion
Item string
}
// Returns true when a feature has been modified.
// This is most important when updating a resource to remove versioned feature usage; if the
// resource is reverting to its base version, it needs to perform a final update at the higher
// version in order to remove high version features.
func (s Feature) HasChangeBy(d TerraformResourceData) bool {
return d.HasChange(s.Item)
}
// Return true when a feature appears in schema or has been modified.
func (s Feature) InUseBy(d TerraformResourceData) bool {
_, ok := d.GetOk(s.Item)
return ok || s.HasChangeBy(d)
}
func maxVersion(versionsInUse map[ComputeApiVersion]struct{}) ComputeApiVersion {
for _, version := range OrderedComputeApiVersions {
if _, ok := versionsInUse[version]; ok {
return version
}
}
// Fallback to the final, most stable version
return OrderedComputeApiVersions[len(OrderedComputeApiVersions)-1]
}