Add expiration policy to pubsub subscription resource (#3525)

Signed-off-by: Modular Magician <magic-modules@google.com>
This commit is contained in:
The Magician 2019-05-03 11:25:50 -07:00 committed by Ty Larrabee
parent 99a0847cb7
commit 07af08027e
3 changed files with 115 additions and 0 deletions

View File

@ -26,6 +26,18 @@ import (
"github.com/hashicorp/terraform/helper/schema"
)
func comparePubsubSubscriptionExpirationPolicy(_, old, new string, _ *schema.ResourceData) bool {
trimmedNew := strings.TrimLeft(new, "0")
trimmedOld := strings.TrimLeft(old, "0")
if strings.Contains(trimmedNew, ".") {
trimmedNew = strings.TrimRight(strings.TrimSuffix(trimmedNew, "s"), "0") + "s"
}
if strings.Contains(trimmedOld, ".") {
trimmedOld = strings.TrimRight(strings.TrimSuffix(trimmedOld, "s"), "0") + "s"
}
return trimmedNew == trimmedOld
}
func resourcePubsubSubscription() *schema.Resource {
return &schema.Resource{
Create: resourcePubsubSubscriptionCreate,
@ -61,6 +73,21 @@ func resourcePubsubSubscription() *schema.Resource {
Computed: true,
Optional: true,
},
"expiration_policy": {
Type: schema.TypeList,
Computed: true,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"ttl": {
Type: schema.TypeString,
Optional: true,
DiffSuppressFunc: comparePubsubSubscriptionExpirationPolicy,
},
},
},
},
"labels": {
Type: schema.TypeMap,
Optional: true,
@ -153,6 +180,12 @@ func resourcePubsubSubscriptionCreate(d *schema.ResourceData, meta interface{})
} else if v, ok := d.GetOkExists("retain_acked_messages"); !isEmptyValue(reflect.ValueOf(retainAckedMessagesProp)) && (ok || !reflect.DeepEqual(v, retainAckedMessagesProp)) {
obj["retainAckedMessages"] = retainAckedMessagesProp
}
expirationPolicyProp, err := expandPubsubSubscriptionExpirationPolicy(d.Get("expiration_policy"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("expiration_policy"); !isEmptyValue(reflect.ValueOf(expirationPolicyProp)) && (ok || !reflect.DeepEqual(v, expirationPolicyProp)) {
obj["expirationPolicy"] = expirationPolicyProp
}
url, err := replaceVars(d, config, "https://pubsub.googleapis.com/v1/projects/{{project}}/subscriptions/{{name}}")
if err != nil {
@ -224,6 +257,9 @@ func resourcePubsubSubscriptionRead(d *schema.ResourceData, meta interface{}) er
if err := d.Set("retain_acked_messages", flattenPubsubSubscriptionRetainAckedMessages(res["retainAckedMessages"], d)); err != nil {
return fmt.Errorf("Error reading Subscription: %s", err)
}
if err := d.Set("expiration_policy", flattenPubsubSubscriptionExpirationPolicy(res["expirationPolicy"], d)); err != nil {
return fmt.Errorf("Error reading Subscription: %s", err)
}
return nil
}
@ -262,6 +298,12 @@ func resourcePubsubSubscriptionUpdate(d *schema.ResourceData, meta interface{})
} else if v, ok := d.GetOkExists("retain_acked_messages"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, retainAckedMessagesProp)) {
obj["retainAckedMessages"] = retainAckedMessagesProp
}
expirationPolicyProp, err := expandPubsubSubscriptionExpirationPolicy(d.Get("expiration_policy"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("expiration_policy"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, expirationPolicyProp)) {
obj["expirationPolicy"] = expirationPolicyProp
}
obj, err = resourcePubsubSubscriptionUpdateEncoder(d, meta, obj)
if err != nil {
@ -295,6 +337,10 @@ func resourcePubsubSubscriptionUpdate(d *schema.ResourceData, meta interface{})
if d.HasChange("retain_acked_messages") {
updateMask = append(updateMask, "retainAckedMessages")
}
if d.HasChange("expiration_policy") {
updateMask = append(updateMask, "expirationPolicy")
}
// updateMask is a URL parameter but not present in the schema, so replaceVars
// won't set it
url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
@ -404,6 +450,23 @@ func flattenPubsubSubscriptionRetainAckedMessages(v interface{}, d *schema.Resou
return v
}
func flattenPubsubSubscriptionExpirationPolicy(v interface{}, d *schema.ResourceData) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["ttl"] =
flattenPubsubSubscriptionExpirationPolicyTtl(original["ttl"], d)
return []interface{}{transformed}
}
func flattenPubsubSubscriptionExpirationPolicyTtl(v interface{}, d *schema.ResourceData) interface{} {
return v
}
func expandPubsubSubscriptionName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
project, err := getProject(d, config)
if err != nil {
@ -511,6 +574,29 @@ func expandPubsubSubscriptionRetainAckedMessages(v interface{}, d TerraformResou
return v, nil
}
func expandPubsubSubscriptionExpirationPolicy(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil, nil
}
raw := l[0]
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})
transformedTtl, err := expandPubsubSubscriptionExpirationPolicyTtl(original["ttl"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedTtl); val.IsValid() && !isEmptyValue(val) {
transformed["ttl"] = transformedTtl
}
return transformed, nil
}
func expandPubsubSubscriptionExpirationPolicyTtl(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}
func resourcePubsubSubscriptionUpdateEncoder(d *schema.ResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) {
newObj := make(map[string]interface{})
newObj["subscription"] = obj

View File

@ -67,6 +67,10 @@ resource "google_pubsub_subscription" "example" {
retain_acked_messages = true
ack_deadline_seconds = 20
expiration_policy {
ttl = "300000.5s"
}
}
`, context)
}

View File

@ -85,6 +85,10 @@ resource "google_pubsub_subscription" "example" {
retain_acked_messages = true
ack_deadline_seconds = 20
expiration_policy {
ttl = "300000.5s"
}
}
```
## Example Usage - Pubsub Subscription Different Project
@ -165,6 +169,15 @@ The following arguments are supported:
messages are not expunged from the subscription's backlog, even if
they are acknowledged, until they fall out of the
messageRetentionDuration window.
* `expiration_policy` -
(Optional)
A policy that specifies the conditions for this subscription's expiration.
A subscription is considered active as long as any connected subscriber
is successfully consuming messages from the subscription or is issuing
operations on the subscription. If expirationPolicy is not set, a default
policy with ttl of 31 days will be used. The minimum allowed value for
expirationPolicy.ttl is 1 day. Structure is documented below.
* `project` - (Optional) The ID of the project in which the resource belongs.
If it is not provided, the provider project is used.
@ -198,6 +211,18 @@ The `push_config` block supports:
- v1beta1: uses the push format defined in the v1beta1 Pub/Sub API.
- v1 or v1beta2: uses the push format defined in the v1 Pub/Sub API.
The `expiration_policy` block supports:
* `ttl` -
(Optional)
Specifies the "time-to-live" duration for an associated resource. The
resource expires if it is not active for a period of ttl. The definition
of "activity" depends on the type of the associated resource. The minimum
and maximum allowed values for ttl depend on the type of the associated
resource, as well. If ttl is not set, the associated resource never expires.
A duration in seconds with up to nine fractional digits, terminated by 's'.
Example - "3.5s".
## Attributes Reference
In addition to the arguments listed above, the following computed attributes are exported: