Skip to content

Commit

Permalink
add souce repo support to cloud functions (#2650)
Browse files Browse the repository at this point in the history
  • Loading branch information
modular-magician authored and danawillow committed Dec 13, 2018
1 parent 2f490f0 commit e4cbc2e
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 9 deletions.
68 changes: 63 additions & 5 deletions google/resource_cloudfunctions_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,31 @@ func resourceCloudFunctionsFunction() *schema.Resource {

"source_archive_bucket": {
Type: schema.TypeString,
Required: true,
Optional: true,
},

"source_archive_object": {
Type: schema.TypeString,
Required: true,
Optional: true,
},

"source_repository": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
ConflictsWith: []string{"source_archive_bucket", "source_archive_object"},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"url": {
Type: schema.TypeString,
Required: true,
},
"deployed_url": {
Type: schema.TypeString,
Computed: true,
},
},
},
},

"description": {
Expand Down Expand Up @@ -302,9 +321,17 @@ func resourceCloudFunctionsCreate(d *schema.ResourceData, meta interface{}) erro
ForceSendFields: []string{},
}

sourceArchiveBucket := d.Get("source_archive_bucket").(string)
sourceArchiveObj := d.Get("source_archive_object").(string)
function.SourceArchiveUrl = fmt.Sprintf("gs://%v/%v", sourceArchiveBucket, sourceArchiveObj)
sourceRepos := d.Get("source_repository").([]interface{})
if len(sourceRepos) > 0 {
function.SourceRepository = expandSourceRepository(sourceRepos)
} else {
sourceArchiveBucket := d.Get("source_archive_bucket").(string)
sourceArchiveObj := d.Get("source_archive_object").(string)
if sourceArchiveBucket == "" || sourceArchiveObj == "" {
return fmt.Errorf("either source_repository or both of source_archive_bucket+source_archive_object must be set")
}
function.SourceArchiveUrl = fmt.Sprintf("gs://%v/%v", sourceArchiveBucket, sourceArchiveObj)
}

if v, ok := d.GetOk("available_memory_mb"); ok {
availableMemoryMb := v.(int)
Expand Down Expand Up @@ -396,6 +423,7 @@ func resourceCloudFunctionsRead(d *schema.ResourceData, meta interface{}) error
d.Set("source_archive_bucket", bucket)
d.Set("source_archive_object", object)
}
d.Set("source_repository", flattenSourceRepository(function.SourceRepository))

if function.HttpsTrigger != nil {
d.Set("trigger_http", true)
Expand Down Expand Up @@ -444,6 +472,11 @@ func resourceCloudFunctionsUpdate(d *schema.ResourceData, meta interface{}) erro
updateMaskArr = append(updateMaskArr, "sourceArchiveUrl")
}

if d.HasChange("source_repository") {
function.SourceRepository = expandSourceRepository(d.Get("source_repository").([]interface{}))
updateMaskArr = append(updateMaskArr, "sourceRepository")
}

if d.HasChange("description") {
function.Description = d.Get("description").(string)
updateMaskArr = append(updateMaskArr, "description")
Expand Down Expand Up @@ -608,3 +641,28 @@ func flattenFailurePolicy(failurePolicy *cloudfunctions.FailurePolicy) []map[str

return result
}

func expandSourceRepository(configured []interface{}) *cloudfunctions.SourceRepository {
if len(configured) == 0 || configured[0] == nil {
return &cloudfunctions.SourceRepository{}
}

data := configured[0].(map[string]interface{})
return &cloudfunctions.SourceRepository{
Url: data["url"].(string),
}
}

func flattenSourceRepository(sourceRepo *cloudfunctions.SourceRepository) []map[string]interface{} {
result := make([]map[string]interface{}, 0, 1)
if sourceRepo == nil {
return nil
}

result = append(result, map[string]interface{}{
"url": sourceRepo.Url,
"deployed_url": sourceRepo.DeployedUrl,
})

return result
}
42 changes: 42 additions & 0 deletions google/resource_cloudfunctions_function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,29 @@ func TestAccCloudFunctionsFunction_firestore(t *testing.T) {
})
}

func TestAccCloudFunctionsFunction_sourceRepo(t *testing.T) {
t.Parallel()

funcResourceName := "google_cloudfunctions_function.function"
functionName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudFunctionsFunctionDestroy,
Steps: []resource.TestStep{
{
Config: testAccCloudFunctionsFunction_sourceRepo(functionName),
},
{
ResourceName: funcResourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccCheckCloudFunctionsFunctionDestroy(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)

Expand Down Expand Up @@ -564,3 +587,22 @@ resource "google_cloudfunctions_function" "function" {
}
}`, bucketName, zipFilePath, functionName)
}

func testAccCloudFunctionsFunction_sourceRepo(functionName string) string {
return fmt.Sprintf(`
resource "google_cloudfunctions_function" "function" {
name = "%s"
source_repository {
// There isn't yet an API that'll allow us to create a source repository and
// put code in it, so we created this repository outside the test to be used
// here. If this test is run outside of CI, it may fail because of permissions
// errors.
url = "https://source.developers.google.com/projects/hc-terraform-testing/repos/cloudfunctions-test-do-not-delete/moveable-aliases/master/paths/"
}
trigger_http = true
entry_point = "helloGET"
}
`, functionName)
}
21 changes: 17 additions & 4 deletions website/docs/r/cloudfunctions_function.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@ The following arguments are supported:

* `name` - (Required) A user-defined name of the function. Function names must be unique globally.

* `source_archive_bucket` - (Required) The GCS bucket containing the zip archive which contains the function.

* `source_archive_object` - (Required) The source archive object (file) in archive bucket.

- - -

* `description` - (Optional) Description of the function.
Expand All @@ -74,6 +70,13 @@ The following arguments are supported:

* `environment_variables` - (Optional) A set of key/value environment variable pairs to assign to the function.

* `source_archive_bucket` - (Optional) The GCS bucket containing the zip archive which contains the function.

* `source_archive_object` - (Optional) The source archive object (file) in archive bucket.

* `source_repository` - (Optional) Represents parameters related to source repository where a function is hosted.
Cannot be set alongside `source_archive_bucket` or `source_archive_object`. Structure is documented below.

The `event_trigger` block supports:

* `event_type` - (Required) The type of event to observe. For example: `"google.storage.object.finalize"`.
Expand All @@ -90,13 +93,23 @@ The `failure_policy` block supports:

* `retry` - (Required) Whether the function should be retried on failure. Defaults to `false`.

The `source_reposoitory` block supports:

* `url` - (Required) The URL pointing to the hosted repository where the function is defined. There are supported Cloud Source Repository URLs in the following formats:

* To refer to a specific commit: `https://source.developers.google.com/projects/*/repos/*/revisions/*/paths/*`
* To refer to a moveable alias (branch): `https://source.developers.google.com/projects/*/repos/*/moveable-aliases/*/paths/*`. To refer to HEAD, use the `master` moveable alias.
* To refer to a specific fixed alias (tag): `https://source.developers.google.com/projects/*/repos/*/fixed-aliases/*/paths/*`

## Attributes Reference

In addition to the arguments listed above, the following computed attributes are
exported:

* `https_trigger_url` - URL which triggers function execution. Returned only if `trigger_http` is used.

* `source_reposoitory.0.deployed_url` - The URL pointing to the hosted repository where the function was defined at the time of deployment.

* `project` - Project of the function. If it is not provided, the provider project is used.

* `region` - Region of function. Currently can be only "us-central1". If it is not provided, the provider region is used.
Expand Down

0 comments on commit e4cbc2e

Please sign in to comment.