diff --git a/google/resource_cloudbuild_build_trigger.go b/google/resource_cloudbuild_build_trigger.go index 8009a687e0c..7b5daf704bd 100644 --- a/google/resource_cloudbuild_build_trigger.go +++ b/google/resource_cloudbuild_build_trigger.go @@ -17,6 +17,7 @@ func resourceCloudBuildTrigger() *schema.Resource { return &schema.Resource{ Create: resourceCloudbuildBuildTriggerCreate, Read: resourceCloudbuildBuildTriggerRead, + Update: resourceCloudbuildBuildTriggerUpdate, Delete: resourceCloudbuildBuildTriggerDelete, Importer: &schema.ResourceImporter{ State: resourceCloudBuildTriggerImportState, @@ -39,38 +40,32 @@ func resourceCloudBuildTrigger() *schema.Resource { "filename": &schema.Schema{ Type: schema.TypeString, Optional: true, - ForceNew: true, ConflictsWith: []string{"build"}, }, "build": { Type: schema.TypeList, Description: "Contents of the build template.", Optional: true, - ForceNew: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "images": &schema.Schema{ Type: schema.TypeList, Optional: true, - ForceNew: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "step": &schema.Schema{ Type: schema.TypeList, Optional: true, - ForceNew: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": &schema.Schema{ Type: schema.TypeString, Optional: true, - ForceNew: true, }, "args": &schema.Schema{ Type: schema.TypeString, Optional: true, - ForceNew: true, }, }, }, @@ -78,7 +73,6 @@ func resourceCloudBuildTrigger() *schema.Resource { "tags": &schema.Schema{ Type: schema.TypeList, Optional: true, - ForceNew: true, Elem: &schema.Schema{Type: schema.TypeString}, }, }, @@ -87,50 +81,41 @@ func resourceCloudBuildTrigger() *schema.Resource { "description": &schema.Schema{ Type: schema.TypeString, Optional: true, - ForceNew: true, }, "substitutions": &schema.Schema{ Optional: true, Type: schema.TypeMap, - ForceNew: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "trigger_template": &schema.Schema{ Optional: true, Type: schema.TypeList, MaxItems: 1, - ForceNew: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "branch_name": &schema.Schema{ Type: schema.TypeString, Optional: true, - ForceNew: true, }, "commit_sha": &schema.Schema{ Type: schema.TypeString, Optional: true, - ForceNew: true, }, "dir": &schema.Schema{ Type: schema.TypeString, Optional: true, - ForceNew: true, }, "project": &schema.Schema{ Type: schema.TypeString, Optional: true, - ForceNew: true, }, "repo_name": &schema.Schema{ Type: schema.TypeString, Optional: true, - ForceNew: true, }, "tag_name": &schema.Schema{ Type: schema.TypeString, Optional: true, - ForceNew: true, }, }, }, @@ -147,22 +132,11 @@ func resourceCloudbuildBuildTriggerCreate(d *schema.ResourceData, meta interface return err } - // Build the address parameter - buildTrigger := &cloudbuild.BuildTrigger{} - - if v, ok := d.GetOk("description"); ok { - buildTrigger.Description = v.(string) - } - - if v, ok := d.GetOk("filename"); ok { - buildTrigger.Filename = v.(string) - } else { - buildTrigger.Build = expandCloudbuildBuildTriggerBuild(d) + buildTrigger, err := expandCloudbuildBuildTrigger(d, meta) + if err != nil { + return err } - buildTrigger.TriggerTemplate = expandCloudbuildBuildTriggerTemplate(d, project) - buildTrigger.Substitutions = expandStringMap(d, "substitutions") - tstr, err := json.Marshal(buildTrigger) if err != nil { return err @@ -208,6 +182,56 @@ func resourceCloudbuildBuildTriggerRead(d *schema.ResourceData, meta interface{} return nil } +func resourceCloudbuildBuildTriggerUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + buildTrigger, err := expandCloudbuildBuildTrigger(d, meta) + if err != nil { + return err + } + + id := d.Id() + + log.Printf("[INFO] Updating Cloud Build Trigger: %s", id) + + if _, err = config.clientBuild.Projects.Triggers.Patch(project, id, buildTrigger).Do(); err != nil { + return err + } + + return resourceCloudbuildBuildTriggerRead(d, meta) +} + +func expandCloudbuildBuildTrigger(d *schema.ResourceData, meta interface{}) (*cloudbuild.BuildTrigger, error) { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return nil, err + } + + t := &cloudbuild.BuildTrigger{} + + if v, ok := d.GetOk("description"); ok { + t.Description = v.(string) + } + + if v, ok := d.GetOk("filename"); ok { + t.Filename = v.(string) + } else { + t.Build = expandCloudbuildBuildTriggerBuild(d) + } + + t.Substitutions = expandStringMap(d, "substitutions") + t.TriggerTemplate = expandCloudbuildBuildTriggerTemplate(d, project) + + return t, nil +} + func expandCloudbuildBuildTriggerTemplate(d *schema.ResourceData, project string) *cloudbuild.RepoSource { if d.Get("trigger_template.#").(int) == 0 { return nil diff --git a/google/resource_cloudbuild_build_trigger_test.go b/google/resource_cloudbuild_build_trigger_test.go index bc36c2a4c24..2489a8d4be0 100644 --- a/google/resource_cloudbuild_build_trigger_test.go +++ b/google/resource_cloudbuild_build_trigger_test.go @@ -34,6 +34,15 @@ func TestAccCloudBuildTrigger_basic(t *testing.T) { ImportStateVerify: true, ImportStateIdPrefix: fmt.Sprintf("%s/", projectID), }, + resource.TestStep{ + Config: testGoogleCloudBuildTrigger_updated(projectID, projectOrg, projectBillingAccount), + }, + resource.TestStep{ + ResourceName: "google_cloudbuild_trigger.build_trigger", + ImportState: true, + ImportStateVerify: true, + ImportStateIdPrefix: fmt.Sprintf("%s/", projectID), + }, resource.TestStep{ Config: testGoogleCloudBuildTrigger_removed(projectID, projectOrg, projectBillingAccount), Check: resource.ComposeTestCheckFunc( @@ -210,6 +219,59 @@ resource "google_cloudbuild_trigger" "build_trigger" { `, projectID, projectID, projectOrg, projectBillingAccount) } +func testGoogleCloudBuildTrigger_updated(projectID, projectOrg, projectBillingAccount string) string { + return fmt.Sprintf(` +resource "google_project" "acceptance" { + name = "%s" + project_id = "%s" + org_id = "%s" + billing_account = "%s" +} + +resource "google_project_services" "acceptance" { + project = "${google_project.acceptance.project_id}" + + services = [ + "cloudbuild.googleapis.com", + "containerregistry.googleapis.com", + "logging.googleapis.com", + "pubsub.googleapis.com", + "storage-api.googleapis.com", + ] +} + +resource "google_cloudbuild_trigger" "build_trigger" { + project = "${google_project_services.acceptance.project}" + description = "acceptance test build trigger updated" + trigger_template { + branch_name = "master-updated" + project = "${google_project_services.acceptance.project}" + repo_name = "some-repo-updated" + } + build { + images = ["gcr.io/$PROJECT_ID/$REPO_NAME:$SHORT_SHA"] + tags = ["team-a", "service-b", "updated"] + step { + name = "gcr.io/cloud-builders/gsutil" + args = "cp gs://mybucket/remotefile.zip localfile-updated.zip " + } + step { + name = "gcr.io/cloud-builders/go" + args = "build my_package_updated" + } + step { + name = "gcr.io/cloud-builders/docker" + args = "build -t gcr.io/$PROJECT_ID/$REPO_NAME:$SHORT_SHA -f Dockerfile ." + } + step { + name = "gcr.io/$PROJECT_ID/$REPO_NAME:$SHORT_SHA" + args = "test" + } + } +} + `, projectID, projectID, projectOrg, projectBillingAccount) +} + func testGoogleCloudBuildTrigger_filename(projectID, projectOrg, projectBillingAccount string) string { return fmt.Sprintf(` resource "google_project" "acceptance" {