mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-10-01 16:21:06 +00:00
Merge pull request #1995 from terraform-providers/paddy_1916_diff_fix
Fix perma-diff on instance templates.
This commit is contained in:
commit
c1d404ddc1
@ -196,3 +196,39 @@ func resolveImage(c *Config, project, name string) (string, error) {
|
||||
}
|
||||
return "", fmt.Errorf("Could not find image or family %s", name)
|
||||
}
|
||||
|
||||
// resolvedImageSelfLink takes the output of resolveImage and coerces it into a self_link.
|
||||
// In the event that a global/images/IMAGE or global/images/family/FAMILY reference is
|
||||
// returned from resolveImage, providerProject will be used as the project for the self_link.
|
||||
func resolvedImageSelfLink(providerProject, name string) (string, error) {
|
||||
switch {
|
||||
case resolveImageLink.MatchString(name): // https://www.googleapis.com/compute/v1/projects/xyz/global/images/xyz
|
||||
return name, nil
|
||||
case resolveImageProjectImage.MatchString(name): // projects/xyz/global/images/xyz
|
||||
res := resolveImageProjectImage.FindStringSubmatch(name)
|
||||
if err := sanityTestRegexMatches(2, res, "project image", name); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s/global/images/%s", res[1], res[2]), nil
|
||||
case resolveImageProjectFamily.MatchString(name): // projects/xyz/global/images/family/xyz
|
||||
res := resolveImageProjectFamily.FindStringSubmatch(name)
|
||||
if err := sanityTestRegexMatches(2, res, "project family", name); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s/global/images/family/%s", res[1], res[2]), nil
|
||||
case resolveImageGlobalImage.MatchString(name): // global/images/xyz
|
||||
res := resolveImageGlobalImage.FindStringSubmatch(name)
|
||||
if err := sanityTestRegexMatches(1, res, "global image", name); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s/global/images/%s", providerProject, res[1]), nil
|
||||
case resolveImageGlobalFamily.MatchString(name): // global/images/family/xyz
|
||||
res := resolveImageGlobalFamily.FindStringSubmatch(name)
|
||||
if err := sanityTestRegexMatches(1, res, "global family", name); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s/global/images/family/%s", providerProject, res[1]), nil
|
||||
}
|
||||
return "", fmt.Errorf("Could not expand image or family %q into a self_link", name)
|
||||
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
SchemaVersion: 1,
|
||||
CustomizeDiff: resourceComputeInstanceTemplateSourceImageCustomizeDiff,
|
||||
MigrateState: resourceComputeInstanceTemplateMigrateState,
|
||||
|
||||
// A compute instance template is more or less a subset of a compute
|
||||
@ -99,10 +100,9 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
||||
},
|
||||
|
||||
"source_image": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DiffSuppressFunc: compareSelfLinkRelativePaths,
|
||||
ForceNew: true,
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"interface": &schema.Schema{
|
||||
@ -420,6 +420,57 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
||||
}
|
||||
}
|
||||
|
||||
func resourceComputeInstanceTemplateSourceImageCustomizeDiff(diff *schema.ResourceDiff, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
project, err := getProjectFromDiff(diff, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
numDisks := diff.Get("disk.#").(int)
|
||||
for i := 0; i < numDisks; i++ {
|
||||
key := fmt.Sprintf("disk.%d.source_image", i)
|
||||
if diff.HasChange(key) {
|
||||
old, new := diff.GetChange(key)
|
||||
if old == "" || new == "" {
|
||||
// no sense in resolving empty strings
|
||||
err = diff.ForceNew(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
oldResolved, err := resolveImage(config, project, old.(string))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
oldResolved, err = resolvedImageSelfLink(project, oldResolved)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newResolved, err := resolveImage(config, project, new.(string))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newResolved, err = resolvedImageSelfLink(project, newResolved)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if oldResolved != newResolved {
|
||||
err = diff.ForceNew(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
err = diff.Clear(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildDisks(d *schema.ResourceData, config *Config) ([]*computeBeta.AttachedDisk, error) {
|
||||
project, err := getProject(d, config)
|
||||
if err != nil {
|
||||
|
@ -64,6 +64,20 @@ func getProject(d TerraformResourceData, config *Config) (string, error) {
|
||||
return getProjectFromSchema("project", d, config)
|
||||
}
|
||||
|
||||
// getProjectFromDiff reads the "project" field from the given diff and falls
|
||||
// back to the provider's value if not given. If the provider's value is not
|
||||
// given, an error is returned.
|
||||
func getProjectFromDiff(d *schema.ResourceDiff, config *Config) (string, error) {
|
||||
res, ok := d.GetOk("project")
|
||||
if ok {
|
||||
return res.(string), nil
|
||||
}
|
||||
if config.Project != "" {
|
||||
return config.Project, nil
|
||||
}
|
||||
return "", fmt.Errorf("%s: required field is not set", "project")
|
||||
}
|
||||
|
||||
func getProjectFromInstanceState(is *terraform.InstanceState, config *Config) (string, error) {
|
||||
res, ok := is.Attributes["project"]
|
||||
|
||||
|
2
vendor/github.com/hashicorp/terraform/helper/schema/data_source_resource_shim.go
generated
vendored
2
vendor/github.com/hashicorp/terraform/helper/schema/data_source_resource_shim.go
generated
vendored
@ -32,7 +32,7 @@ func DataSourceResourceShim(name string, dataSource *Resource) *Resource {
|
||||
|
||||
// FIXME: Link to some further docs either on the website or in the
|
||||
// changelog, once such a thing exists.
|
||||
dataSource.deprecationMessage = fmt.Sprintf(
|
||||
dataSource.DeprecationMessage = fmt.Sprintf(
|
||||
"using %s as a resource is deprecated; consider using the data source instead",
|
||||
name,
|
||||
)
|
||||
|
8
vendor/github.com/hashicorp/terraform/helper/schema/resource.go
generated
vendored
8
vendor/github.com/hashicorp/terraform/helper/schema/resource.go
generated
vendored
@ -124,9 +124,7 @@ type Resource struct {
|
||||
Importer *ResourceImporter
|
||||
|
||||
// If non-empty, this string is emitted as a warning during Validate.
|
||||
// This is a private interface for now, for use by DataSourceResourceShim,
|
||||
// and not for general use. (But maybe later...)
|
||||
deprecationMessage string
|
||||
DeprecationMessage string
|
||||
|
||||
// Timeouts allow users to specify specific time durations in which an
|
||||
// operation should time out, to allow them to extend an action to suit their
|
||||
@ -269,8 +267,8 @@ func (r *Resource) Diff(
|
||||
func (r *Resource) Validate(c *terraform.ResourceConfig) ([]string, []error) {
|
||||
warns, errs := schemaMap(r.Schema).Validate(c)
|
||||
|
||||
if r.deprecationMessage != "" {
|
||||
warns = append(warns, r.deprecationMessage)
|
||||
if r.DeprecationMessage != "" {
|
||||
warns = append(warns, r.DeprecationMessage)
|
||||
}
|
||||
|
||||
return warns, errs
|
||||
|
1
vendor/github.com/hashicorp/terraform/helper/schema/resource_data.go
generated
vendored
1
vendor/github.com/hashicorp/terraform/helper/schema/resource_data.go
generated
vendored
@ -315,6 +315,7 @@ func (d *ResourceData) State() *terraform.InstanceState {
|
||||
|
||||
mapW := &MapFieldWriter{Schema: d.schema}
|
||||
if err := mapW.WriteField(nil, rawMap); err != nil {
|
||||
log.Printf("[ERR] Error writing fields: %s", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
26
vendor/github.com/hashicorp/terraform/helper/schema/resource_diff.go
generated
vendored
26
vendor/github.com/hashicorp/terraform/helper/schema/resource_diff.go
generated
vendored
@ -231,7 +231,7 @@ func (d *ResourceDiff) UpdatedKeys() []string {
|
||||
// Note that this does not wipe an override. This function is only allowed on
|
||||
// computed keys.
|
||||
func (d *ResourceDiff) Clear(key string) error {
|
||||
if err := d.checkKey(key, "Clear"); err != nil {
|
||||
if err := d.checkKey(key, "Clear", true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -287,7 +287,7 @@ func (d *ResourceDiff) diffChange(key string) (interface{}, interface{}, bool, b
|
||||
//
|
||||
// This function is only allowed on computed attributes.
|
||||
func (d *ResourceDiff) SetNew(key string, value interface{}) error {
|
||||
if err := d.checkKey(key, "SetNew"); err != nil {
|
||||
if err := d.checkKey(key, "SetNew", false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -299,7 +299,7 @@ func (d *ResourceDiff) SetNew(key string, value interface{}) error {
|
||||
//
|
||||
// This function is only allowed on computed attributes.
|
||||
func (d *ResourceDiff) SetNewComputed(key string) error {
|
||||
if err := d.checkKey(key, "SetNewComputed"); err != nil {
|
||||
if err := d.checkKey(key, "SetNewComputed", false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -535,12 +535,24 @@ func childAddrOf(child, parent string) bool {
|
||||
}
|
||||
|
||||
// checkKey checks the key to make sure it exists and is computed.
|
||||
func (d *ResourceDiff) checkKey(key, caller string) error {
|
||||
s, ok := d.schema[key]
|
||||
if !ok {
|
||||
func (d *ResourceDiff) checkKey(key, caller string, nested bool) error {
|
||||
var schema *Schema
|
||||
if nested {
|
||||
keyParts := strings.Split(key, ".")
|
||||
schemaL := addrToSchema(keyParts, d.schema)
|
||||
if len(schemaL) > 0 {
|
||||
schema = schemaL[len(schemaL)-1]
|
||||
}
|
||||
} else {
|
||||
s, ok := d.schema[key]
|
||||
if ok {
|
||||
schema = s
|
||||
}
|
||||
}
|
||||
if schema == nil {
|
||||
return fmt.Errorf("%s: invalid key: %s", caller, key)
|
||||
}
|
||||
if !s.Computed {
|
||||
if !schema.Computed {
|
||||
return fmt.Errorf("%s only operates on computed keys - %s is not one", caller, key)
|
||||
}
|
||||
return nil
|
||||
|
2
vendor/github.com/hashicorp/terraform/helper/schema/schema.go
generated
vendored
2
vendor/github.com/hashicorp/terraform/helper/schema/schema.go
generated
vendored
@ -199,7 +199,7 @@ type Schema struct {
|
||||
Sensitive bool
|
||||
}
|
||||
|
||||
// SchemaDiffSuppresFunc is a function which can be used to determine
|
||||
// SchemaDiffSuppressFunc is a function which can be used to determine
|
||||
// whether a detected diff on a schema element is "valid" or not, and
|
||||
// suppress it from the plan if necessary.
|
||||
//
|
||||
|
6
vendor/github.com/hashicorp/terraform/helper/schema/set.go
generated
vendored
6
vendor/github.com/hashicorp/terraform/helper/schema/set.go
generated
vendored
@ -17,6 +17,12 @@ func HashString(v interface{}) int {
|
||||
return hashcode.String(v.(string))
|
||||
}
|
||||
|
||||
// HashInt hashes integers. If you want a Set of integers, this is the
|
||||
// SchemaSetFunc you want.
|
||||
func HashInt(v interface{}) int {
|
||||
return hashcode.String(strconv.Itoa(v.(int)))
|
||||
}
|
||||
|
||||
// HashResource hashes complex structures that are described using
|
||||
// a *Resource. This is the default set implementation used when a set's
|
||||
// element type is a full resource.
|
||||
|
8
vendor/vendor.json
vendored
8
vendor/vendor.json
vendored
@ -695,12 +695,10 @@
|
||||
"versionExact": "v0.11.2"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "JHxGzmxcIS8NyLX9pGhK5beIra4=",
|
||||
"checksumSHA1": "OOwTGBTHcUmQTPBdyscTMkjApbI=",
|
||||
"path": "github.com/hashicorp/terraform/helper/schema",
|
||||
"revision": "41e50bd32a8825a84535e353c3674af8ce799161",
|
||||
"revisionTime": "2018-04-10T16:50:42Z",
|
||||
"version": "v0.11.2",
|
||||
"versionExact": "v0.11.2"
|
||||
"revision": "35d82b055591e9d47a254e68754216d8849ba67a",
|
||||
"revisionTime": "2018-09-26T21:21:28Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "Fzbv+N7hFXOtrR6E7ZcHT3jEE9s=",
|
||||
|
Loading…
Reference in New Issue
Block a user