Skip to content

Commit

Permalink
Allow partial URIs in Cloud Functions event_trigger.resource (hashico…
Browse files Browse the repository at this point in the history
…rp#1009)

Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
modular-magician authored and rileykarson committed Aug 12, 2019
1 parent 11ceee1 commit 3ddb7b9
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 40 deletions.
76 changes: 38 additions & 38 deletions google-beta/resource_cloudfunctions_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ func validateResourceCloudFunctionsFunctionName(v interface{}, k string) (ws []s
return
}

// based on compareSelfLinkOrResourceName, but less reusable and allows multi-/
// strings in the new state (config) part
func compareSelfLinkOrResourceNameWithMultipleParts(_, old, new string, _ *schema.ResourceData) bool {
return strings.HasSuffix(old, new)
}

func resourceCloudFunctionsFunction() *schema.Resource {
return &schema.Resource{
Create: resourceCloudFunctionsCreate,
Expand Down Expand Up @@ -237,8 +243,9 @@ func resourceCloudFunctionsFunction() *schema.Resource {
Required: true,
},
"resource": {
Type: schema.TypeString,
Required: true,
Type: schema.TypeString,
Required: true,
DiffSuppressFunc: compareSelfLinkOrResourceNameWithMultipleParts,
},
"failure_policy": {
Type: schema.TypeList,
Expand Down Expand Up @@ -562,26 +569,38 @@ func expandEventTrigger(configured []interface{}, project string) *cloudfunction

data := configured[0].(map[string]interface{})
eventType := data["event_type"].(string)
shape := ""
switch {
case strings.HasPrefix(eventType, "google.storage.object."):
shape = "projects/%s/buckets/%s"
case strings.HasPrefix(eventType, "google.pubsub.topic."):
shape = "projects/%s/topics/%s"
// Legacy style triggers
case strings.HasPrefix(eventType, "providers/cloud.storage/eventTypes/"):
shape = "projects/%s/buckets/%s"
case strings.HasPrefix(eventType, "providers/cloud.pubsub/eventTypes/"):
shape = "projects/%s/topics/%s"
case strings.HasPrefix(eventType, "providers/cloud.firestore/eventTypes/"):
// Firestore doesn't not yet support multiple databases, so "(default)" is assumed.
// https://cloud.google.com/functions/docs/calling/cloud-firestore#deploying_your_function
shape = "projects/%s/databases/(default)/documents/%s"
resource := data["resource"].(string)

// if resource starts with "projects/", we can reasonably assume it's a
// partial URI. Otherwise, it's a shortname. Construct a partial URI based
// on the event type if so.
if !strings.HasPrefix(resource, "projects/") {
shape := ""
switch {
case strings.HasPrefix(eventType, "google.storage.object."):
shape = "projects/%s/buckets/%s"
case strings.HasPrefix(eventType, "google.pubsub.topic."):
shape = "projects/%s/topics/%s"
// Legacy style triggers
case strings.HasPrefix(eventType, "providers/cloud.storage/eventTypes/"):
// Note that this is an uncommon way to refer to buckets; normally,
// you'd use to the global URL of the bucket and not the project
// scoped one.
shape = "projects/%s/buckets/%s"
case strings.HasPrefix(eventType, "providers/cloud.pubsub/eventTypes/"):
shape = "projects/%s/topics/%s"
case strings.HasPrefix(eventType, "providers/cloud.firestore/eventTypes/"):
// Firestore doesn't not yet support multiple databases, so "(default)" is assumed.
// https://cloud.google.com/functions/docs/calling/cloud-firestore#deploying_your_function
shape = "projects/%s/databases/(default)/documents/%s"
}

resource = fmt.Sprintf(shape, project, resource)
}

return &cloudfunctions.EventTrigger{
EventType: eventType,
Resource: fmt.Sprintf(shape, project, data["resource"].(string)),
Resource: resource,
FailurePolicy: expandFailurePolicy(data["failure_policy"].([]interface{})),
}
}
Expand All @@ -592,28 +611,9 @@ func flattenEventTrigger(eventTrigger *cloudfunctions.EventTrigger) []map[string
return result
}

resource := ""
switch {
case strings.HasPrefix(eventTrigger.EventType, "google.storage.object."):
resource = GetResourceNameFromSelfLink(eventTrigger.Resource)
case strings.HasPrefix(eventTrigger.EventType, "google.pubsub.topic."):
resource = GetResourceNameFromSelfLink(eventTrigger.Resource)
// Legacy style triggers
case strings.HasPrefix(eventTrigger.EventType, "providers/cloud.storage/eventTypes/"):
resource = GetResourceNameFromSelfLink(eventTrigger.Resource)
case strings.HasPrefix(eventTrigger.EventType, "providers/cloud.pubsub/eventTypes/"):
resource = GetResourceNameFromSelfLink(eventTrigger.Resource)
case strings.HasPrefix(eventTrigger.EventType, "providers/cloud.firestore/eventTypes/"):
// Simply taking the substring after the last "/" is not sufficient for firestore as resources may have slashes.
// For the eventTrigger.Resource "projects/my-project/databases/(default)/documents/messages/{messageId}" we extract
// the resource "messages/{messageId}" by taking the everything after the 5th "/"
parts := strings.SplitN(eventTrigger.Resource, "/", 6)
resource = parts[len(parts)-1]
}

result = append(result, map[string]interface{}{
"event_type": eventTrigger.EventType,
"resource": resource,
"resource": eventTrigger.Resource,
"failure_policy": flattenFailurePolicy(eventTrigger.FailurePolicy),
})

Expand Down
4 changes: 3 additions & 1 deletion google-beta/resource_cloudfunctions_function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,8 @@ resource "google_cloudfunctions_function" "function" {
func testAccCloudFunctionsFunction_bucket(functionName string, bucketName string,
zipFilePath string) string {
return fmt.Sprintf(`
data "google_client_config" "current" {}
resource "google_storage_bucket" "bucket" {
name = "%s"
}
Expand All @@ -599,7 +601,7 @@ resource "google_cloudfunctions_function" "function" {
entry_point = "helloGCS"
event_trigger {
event_type = "google.storage.object.finalize"
resource = "${google_storage_bucket.bucket.name}"
resource = "projects/${data.google_client_config.current.project}/buckets/${google_storage_bucket.bucket.name}"
failure_policy {
retry = true
}
Expand Down
3 changes: 2 additions & 1 deletion website/docs/r/cloudfunctions_function.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ Cloud Storage, Cloud Pub/Sub and Cloud Firestore triggers are supported at this
Legacy triggers are supported, such as `"providers/cloud.storage/eventTypes/object.change"`,
`"providers/cloud.pubsub/eventTypes/topic.publish"` and `"providers/cloud.firestore/eventTypes/document.create"`.

* `resource` - (Required) Required. The name of the resource from which to observe events, for example, `"myBucket"`
* `resource` - (Required) Required. The name or partial URI of the resource from
which to observe events. For example, `"myBucket"` or `"projects/my-project/topics/my-topic"`

* `failure_policy` - (Optional) Specifies policy for failed executions. Structure is documented below.

Expand Down

0 comments on commit 3ddb7b9

Please sign in to comment.