Add scaffolding to enable beta features in GKE resources (#1085)

* make api_versions more generic

* add api versions for gke
This commit is contained in:
Dana Hoffman 2018-02-15 18:37:36 -05:00 committed by GitHub
parent 4b1fdee504
commit 7977d277ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 22 deletions

View File

@ -6,18 +6,24 @@ import (
"strings"
)
type ComputeApiVersion uint8
type ApiVersion uint8
const (
v1 ComputeApiVersion = iota
v1 ApiVersion = iota
v0beta
v1beta1
)
var OrderedComputeApiVersions = []ComputeApiVersion{
var OrderedComputeApiVersions = []ApiVersion{
v0beta,
v1,
}
var OrderedContainerApiVersions = []ApiVersion{
v1beta1,
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.
@ -45,22 +51,30 @@ type TerraformResourceData interface {
// 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{}{}}
func getApiVersion(d TerraformResourceData, resourceVersion ApiVersion, features []Feature, maxVersionFunc func(map[ApiVersion]struct{}) ApiVersion) ApiVersion {
versions := map[ApiVersion]struct{}{resourceVersion: struct{}{}}
for _, feature := range features {
if feature.InUseByDefault(d) {
versions[feature.Version] = struct{}{}
}
}
return maxVersion(versions)
return maxVersionFunc(versions)
}
func getComputeApiVersion(d TerraformResourceData, resourceVersion ApiVersion, features []Feature) ApiVersion {
return getApiVersion(d, resourceVersion, features, maxComputeVersion)
}
func getContainerApiVersion(d TerraformResourceData, resourceVersion ApiVersion, features []Feature) ApiVersion {
return getApiVersion(d, resourceVersion, features, maxContainerVersion)
}
// 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{}{}}
func getApiVersionUpdate(d TerraformResourceData, resourceVersion ApiVersion, features, updateOnlyFields []Feature, maxVersionFunc func(map[ApiVersion]struct{}) ApiVersion) ApiVersion {
versions := map[ApiVersion]struct{}{resourceVersion: struct{}{}}
for _, feature := range features {
if feature.InUseByUpdate(d) {
@ -74,12 +88,20 @@ func getComputeApiVersionUpdate(d TerraformResourceData, resourceVersion Compute
}
}
return maxVersion(versions)
return maxVersionFunc(versions)
}
func getComputeApiVersionUpdate(d TerraformResourceData, resourceVersion ApiVersion, features, updateOnlyFields []Feature) ApiVersion {
return getApiVersionUpdate(d, resourceVersion, features, updateOnlyFields, maxComputeVersion)
}
func getContainerApiVersionUpdate(d TerraformResourceData, resourceVersion ApiVersion, features, updateOnlyFields []Feature) ApiVersion {
return getApiVersionUpdate(d, resourceVersion, features, updateOnlyFields, maxContainerVersion)
}
// A field of a resource and the version of the Compute API required to use it.
type Feature struct {
Version ComputeApiVersion
Version ApiVersion
// Path to the beta field.
//
// The feature is considered to be in-use if the field referenced by "Item" is set in the state.
@ -157,13 +179,21 @@ func inUseBy(d TerraformResourceData, path string, defaultValue interface{}, inU
return false
}
func maxVersion(versionsInUse map[ComputeApiVersion]struct{}) ComputeApiVersion {
for _, version := range OrderedComputeApiVersions {
func maxVersion(versionsInUse map[ApiVersion]struct{}, orderedVersions []ApiVersion) ApiVersion {
for _, version := range orderedVersions {
if _, ok := versionsInUse[version]; ok {
return version
}
}
// Fallback to the final, most stable version
return OrderedComputeApiVersions[len(OrderedComputeApiVersions)-1]
return orderedVersions[len(orderedVersions)-1]
}
func maxComputeVersion(versionsInUse map[ApiVersion]struct{}) ApiVersion {
return maxVersion(versionsInUse, OrderedComputeApiVersions)
}
func maxContainerVersion(versionsInUse map[ApiVersion]struct{}) ApiVersion {
return maxVersion(versionsInUse, OrderedContainerApiVersions)
}

View File

@ -3,14 +3,20 @@ package google
import "testing"
type ExpectedApiVersions struct {
Create ComputeApiVersion
ReadDelete ComputeApiVersion
Update ComputeApiVersion
Create ApiVersion
ReadDelete ApiVersion
Update ApiVersion
}
func TestComputeApiVersion(t *testing.T) {
func TestApiVersion(t *testing.T) {
baseVersion := v1
betaVersion := v0beta
maxTestApiVersion := func(versionsInUse map[ApiVersion]struct{}) ApiVersion {
if _, ok := versionsInUse[betaVersion]; ok {
return betaVersion
}
return baseVersion
}
cases := map[string]struct {
Features []Feature
@ -173,7 +179,7 @@ func TestComputeApiVersion(t *testing.T) {
FieldsWithHasChange: keys,
}
apiVersion := getComputeApiVersion(d, v1, tc.Features)
apiVersion := getApiVersion(d, v1, tc.Features, maxTestApiVersion)
if apiVersion != tc.ExpectedApiVersions.Create {
t.Errorf("bad: %s, Expected to see version %v for create, got version %v", tn, tc.ExpectedApiVersions.Create, apiVersion)
}
@ -184,7 +190,7 @@ func TestComputeApiVersion(t *testing.T) {
FieldsInSchema: tc.FieldsInSchema,
}
apiVersion = getComputeApiVersion(d, v1, tc.Features)
apiVersion = getApiVersion(d, v1, tc.Features, maxTestApiVersion)
if apiVersion != tc.ExpectedApiVersions.ReadDelete {
t.Errorf("bad: %s, Expected to see version %v for read/delete, got version %v", tn, tc.ExpectedApiVersions.ReadDelete, apiVersion)
}
@ -196,7 +202,7 @@ func TestComputeApiVersion(t *testing.T) {
FieldsWithHasChange: tc.UpdatedFields,
}
apiVersion = getComputeApiVersionUpdate(d, v1, tc.Features, tc.UpdateOnlyFields)
apiVersion = getApiVersionUpdate(d, v1, tc.Features, tc.UpdateOnlyFields, maxTestApiVersion)
if apiVersion != tc.ExpectedApiVersions.Update {
t.Errorf("bad: %s, Expected to see version %v for update, got version %v", tn, tc.ExpectedApiVersions.Update, apiVersion)
}

View File

@ -330,7 +330,7 @@ func resourceComputeGlobalForwardingRuleDelete(d *schema.ResourceData, meta inte
// resourceComputeGlobalForwardingRuleReadLabelFingerprint performs a read on the remote resource and returns only the
// fingerprint. Used on create when setting labels as we don't know the label fingerprint initially.
func resourceComputeGlobalForwardingRuleReadLabelFingerprint(config *Config, computeApiVersion ComputeApiVersion,
func resourceComputeGlobalForwardingRuleReadLabelFingerprint(config *Config, computeApiVersion ApiVersion,
project, name string) (string, error) {
switch computeApiVersion {
case v0beta:
@ -348,7 +348,7 @@ func resourceComputeGlobalForwardingRuleReadLabelFingerprint(config *Config, com
}
// resourceComputeGlobalForwardingRuleSetLabels sets the Labels attribute on a forwarding rule.
func resourceComputeGlobalForwardingRuleSetLabels(config *Config, computeApiVersion ComputeApiVersion, project,
func resourceComputeGlobalForwardingRuleSetLabels(config *Config, computeApiVersion ApiVersion, project,
name string, labels map[string]string, fingerprint string) error {
var op interface{}
var err error