Skip to content
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
9 changes: 9 additions & 0 deletions pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ func Provider() *schema.Provider {
Optional: true,
},

"deletion_policy": {
Type: schema.TypeString,
Optional: true,
},

"request_reason": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -275,6 +280,10 @@ func ProviderConfigure(ctx context.Context, d *schema.ResourceData, p *schema.Pr
}
}

if v, ok := d.GetOk("deletion_policy"); ok {
config.DeletionPolicy = v.(string)
}

if v, ok := d.GetOk("request_reason"); ok {
config.RequestReason = v.(string)
}
Expand Down
10 changes: 8 additions & 2 deletions pkg/services/alloydb/alloydb_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -713,8 +713,14 @@ This can happen due to user-triggered updates or system actions like failover or
Description: `Policy to determine if the cluster should be deleted forcefully.
Deleting a cluster forcefully, deletes the cluster and all its associated instances within the cluster.
Deleting a Secondary cluster with a secondary instance REQUIRES setting deletion_policy = "FORCE" otherwise an error is returned. This is needed as there is no support to delete just the secondary instance, and the only way to delete secondary instance is to delete the associated secondary cluster forcefully which also deletes the secondary instance.
Possible values: DEFAULT, FORCE`,
Default: "DEFAULT",

When a 'terraform destroy' or 'terraform apply' would delete the resource,
the command will fail if this field is set to "PREVENT" in Terraform state.
When set to "ABANDON", the command will remove the resource from Terraform
management without updating or deleting the resource in the API.
When set to "DELETE", the command will behave as if set to "DEFAULT".

Possible values: DEFAULT, FORCE, PREVENT, ABANDON, DELETE`,
},
"deletion_protection": {
Type: schema.TypeBool,
Expand Down
8 changes: 6 additions & 2 deletions pkg/services/datastream/datastream_private_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,12 @@ Format: projects/{project}/global/{networks}/{name}`,
Description: `The deletion policy for the private connection. Setting 'FORCE' will also delete any child
routes that belong to this private connection. Setting 'DEFAULT' will fail the delete if
child routes exist. Defaults to 'FORCE' for backwards compatibility.
Possible values: 'DEFAULT', 'FORCE'.`,
Default: "FORCE",

When a 'terraform destroy' or 'terraform apply' would delete the resource,
the command will fail if this field is set to "PREVENT" in Terraform state.
When set to "ABANDON", the command will remove the resource from Terraform
management without updating or deleting the resource in the API.
When set to "DELETE", the command will behave as if set to "DEFAULT".`,
},
"project": {
Type: schema.TypeString,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,14 @@ service.`,
Service to be deleted even if a Schema or Connector is present. By default,
the Service deletion will only succeed when no Schema or Connectors are
present.
Possible values: DEFAULT, FORCE`,
Default: "DEFAULT",

When a 'terraform destroy' or 'terraform apply' would delete the resource,
the command will fail if this field is set to "PREVENT" in Terraform state.
When set to "ABANDON", the command will remove the resource from Terraform
management without updating or deleting the resource in the API.
When set to "DELETE", the command will behave as if set to "DEFAULT".

Possible values: DEFAULT, FORCE, PREVENT, ABANDON, DELETE`,
},
"project": {
Type: schema.TypeString,
Expand Down
11 changes: 9 additions & 2 deletions pkg/services/looker/looker_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -596,8 +596,15 @@ accurate to nanoseconds.`,
Description: `Policy to determine if the cluster should be deleted forcefully.
If setting deletion_policy = "FORCE", the Looker instance will be deleted regardless
of its nested resources. If set to "DEFAULT", Looker instances that still have
nested resources will return an error. Possible values: DEFAULT, FORCE`,
Default: "DEFAULT",
nested resources will return an error.

When a 'terraform destroy' or 'terraform apply' would delete the resource,
the command will fail if this field is set to "PREVENT" in Terraform state.
When set to "ABANDON", the command will remove the resource from Terraform
management without updating or deleting the resource in the API.
When set to "DELETE", the command will behave as if set to "DEFAULT".

Possible values: DEFAULT, FORCE, PREVENT, ABANDON, DELETE`,
},
"project": {
Type: schema.TypeString,
Expand Down
10 changes: 8 additions & 2 deletions pkg/services/netapp/netapp_volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -852,8 +852,14 @@ Only applicable to Flex service level.`,
Description: `Policy to determine if the volume should be deleted forcefully.
Volumes may have nested snapshot resources. Deleting such a volume will fail.
Setting this parameter to FORCE will delete volumes including nested snapshots.
Possible values: DEFAULT, FORCE.`,
Default: "DEFAULT",

When a 'terraform destroy' or 'terraform apply' would delete the resource,
the command will fail if this field is set to "PREVENT" in Terraform state.
When set to "ABANDON", the command will remove the resource from Terraform
management without updating or deleting the resource in the API.
When set to "DELETE", the command will behave as if set to "DEFAULT".

Possible values: DEFAULT, FORCE, PREVENT, ABANDON, DELETE.`,
},
"project": {
Type: schema.TypeString,
Expand Down
11 changes: 8 additions & 3 deletions pkg/services/secretmanager/secretmanager_secret_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,16 @@ the provider project is used`,
Optional: true,
Description: `The deletion policy for the secret version. Setting 'ABANDON' allows the resource
to be abandoned rather than deleted. Setting 'DISABLE' allows the resource to be
disabled rather than deleted. Default is 'DELETE'. Possible values are:
disabled rather than deleted.

When a 'terraform destroy' or 'terraform apply' would delete the resource,
the command will fail if this field is set to "PREVENT" in Terraform state.

Default is 'DELETE'. Possible values are:
* DELETE
* DISABLE
* ABANDON`,
Default: "DELETE",
* ABANDON
* PREVENT`,
},
"is_secret_data_base64": {
Type: schema.TypeBool,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,18 @@ func ResourceSecretManagerRegionalRegionalSecretVersion() *schema.Resource {
"deletion_policy": {
Type: schema.TypeString,
Optional: true,
Description: `The deletion policy for the regional secret version. Setting 'ABANDON' allows the resource
Description: `The deletion policy for the secret version. Setting 'ABANDON' allows the resource
to be abandoned rather than deleted. Setting 'DISABLE' allows the resource to be
disabled rather than deleted. Default is 'DELETE'. Possible values are:
disabled rather than deleted.

When a 'terraform destroy' or 'terraform apply' would delete the resource,
the command will fail if this field is set to "PREVENT" in Terraform state.

Default is 'DELETE'. Possible values are:
* DELETE
* DISABLE
* ABANDON`,
Default: "DELETE",
* ABANDON
* PREVENT`,
},
"is_secret_data_base64": {
Type: schema.TypeBool,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,19 +228,6 @@ If unset, defaults to the Google OIDC IdP.`,
Computed: true,
Description: `Time the Instance was updated in UTC.`,
},
"deletion_policy": {
Type: schema.TypeString,
Optional: true,
Description: `The deletion policy for the instance. Setting 'ABANDON' allows the resource
to be abandoned, rather than deleted. Setting 'DELETE' deletes the resource
and all its contents. Setting 'PREVENT' prevents the resource from accidental
deletion by erroring out during plan.
Default is 'PREVENT'. Possible values are:
* DELETE
* PREVENT
* ABANDON`,
Default: "PREVENT",
},
"project": {
Type: schema.TypeString,
Optional: true,
Expand Down
96 changes: 96 additions & 0 deletions pkg/tpgresource/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,88 @@ func GetZoneFromDiff(d *schema.ResourceDiff, config *transport_tpg.Config) (stri
return "", fmt.Errorf("%s: required field is not set", "zone")
}

// getDeletionPolicyFromDiff reads the "deletion_policy" 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 GetDeletionPolicyFromDiff(d *schema.ResourceDiff, config *transport_tpg.Config, resourceDefault string) (string, error) {
//if IsNull() value, then the value has not been manually configured
if d.GetRawConfig().GetAttr("deletion_policy").IsNull() {
if config.DeletionPolicy != "" {
log.Printf("[DEBUG] `deletion_policy` detected as not set within resource configuration. Falling back to configured provider default, %s", config.DeletionPolicy)
return config.DeletionPolicy, nil
}
//return the provided resource default as the final backup
log.Printf("[DEBUG] `deletion_policy` detected as not set within resource or provider configuration. Falling back to resource default, %s", resourceDefault)
return resourceDefault, nil
}
//if not null, then use/maintain usage of manually configured value
//
//this has to happen after a check for the null is made,
//as "GetOk" will always return a value once the resource is set, preventing changes
res, ok := d.GetOk("deletion_policy")
if ok {
return res.(string), nil
}
return "", fmt.Errorf("An error has occured during %s configuration. Please report this issue to the provider developers.", "`deletion_policy`")
}

func DeletionPolicySchemaEntry(resourceDefault string) *schema.Schema {
return &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: fmt.Sprintf(`Whether Terraform will be prevented from destroying the instance. Defaults to "%s".
When a 'terraform destroy' or 'terraform apply' would delete the instance,
the command will fail if this field is set to "PREVENT" in Terraform state.
When set to "ABANDON", the command will remove the resource from Terraform
management without updating or deleting the resource in the API.
When set to "DELETE", deleting the resource is allowed.
`, resourceDefault),
}
}

func DeletionPolicyReadDefault(d *schema.ResourceData, config *transport_tpg.Config, resourceDefault string) error {
if _, ok := d.GetOkExists("deletion_policy"); !ok {
//prioritize config's value if present
if config.DeletionPolicy != "" {
if err := d.Set("deletion_policy", config.DeletionPolicy); err != nil {
return fmt.Errorf("Error setting deletion_policy: %s", err)
}
} else {
if err := d.Set("deletion_policy", resourceDefault); err != nil {
return fmt.Errorf("Error setting deletion_policy: %s", err)
}
}
}
return nil
}

func DeletionPolicyPreUpdate(d *schema.ResourceData, resourceSchema func() *schema.Resource) bool {
clientSideFields := map[string]bool{"deletion_policy": true}
clientSideOnly := true
for field := range resourceSchema().Schema {
if d.HasChange(field) && !clientSideFields[field] {
return false
}
}
if clientSideOnly {
log.Print("[DEBUG] Only client-side changes detected. Cancelling update operation.")
return true
}
return false
}

func DeletionPolicyPreDelete(d *schema.ResourceData) (bool, error) {
if d.Get("deletion_policy").(string) == "PREVENT" {
return true, fmt.Errorf("cannot destroy %q without setting deletion_policy=\"DELETE\" and running `terraform apply`", d.Id())
}
if d.Get("deletion_policy").(string) == "ABANDON" {
log.Printf("[DEBUG] deletion_policy set to \"ABANDON\", removing %q from Terraform state without deletion", d.Id())
return true, nil
}
return false, nil
}

func GetRouterLockName(region string, router string) string {
return fmt.Sprintf("router/%s/%s", region, router)
}
Expand Down Expand Up @@ -901,6 +983,20 @@ func DefaultProviderZone(_ context.Context, diff *schema.ResourceDiff, meta inte
return nil
}

func DefaultProviderDeletionPolicy(resourceDefault string) schema.CustomizeDiffFunc {
return func(_ context.Context, diff *schema.ResourceDiff, meta interface{}) error {
config := meta.(*transport_tpg.Config)
if dpolicy := diff.Get("deletion_policy"); dpolicy != nil {
dpolicy, err := GetDeletionPolicyFromDiff(diff, config, resourceDefault)
err = diff.SetNew("deletion_policy", dpolicy)
if err != nil {
return err
}
}
return nil
}
}

// id.UniqueId() returns a timestamp + incremental hash
// This function truncates the timestamp to provide a prefix + 9 using
// YYmmdd + last 3 digits of the incremental hash
Expand Down
2 changes: 2 additions & 0 deletions pkg/transport/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ type Config struct {
DefaultLabels map[string]string
AddTerraformAttributionLabel bool
TerraformAttributionLabelAdditionStrategy string
DeletionPolicy string

// PollInterval is passed to retry.StateChangeConf in common_operation.go
// It controls the interval at which we poll for successful operations
PollInterval time.Duration
Expand Down