From 259ec21b874cda72c699c04688f2e2ac5387d902 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Mon, 9 Apr 2018 17:53:10 -0400 Subject: [PATCH 1/2] resource/aws_codebuild_project: Properly handle setting cache type NO_CACHE --- aws/resource_aws_codebuild_project.go | 49 +++++++++++++------ aws/resource_aws_codebuild_project_test.go | 25 ++++++++-- .../docs/r/codebuild_project.html.markdown | 4 +- 3 files changed, 56 insertions(+), 22 deletions(-) diff --git a/aws/resource_aws_codebuild_project.go b/aws/resource_aws_codebuild_project.go index e6d92150aee..95724b9b66d 100644 --- a/aws/resource_aws_codebuild_project.go +++ b/aws/resource_aws_codebuild_project.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/codebuild" + "github.com/hashicorp/terraform/helper/customdiff" "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" @@ -69,13 +70,19 @@ func resourceAwsCodeBuildProject() *schema.Resource { "cache": { Type: schema.TypeList, Optional: true, - Computed: true, MaxItems: 1, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == "1" && new == "0" { + return true + } + return false + }, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "type": { Type: schema.TypeString, - Required: true, + Optional: true, + Default: codebuild.CacheTypeNoCache, ValidateFunc: validation.StringInSlice([]string{ codebuild.CacheTypeNoCache, codebuild.CacheTypeS3, @@ -83,7 +90,7 @@ func resourceAwsCodeBuildProject() *schema.Resource { }, "location": { Type: schema.TypeString, - Required: true, + Optional: true, }, }, }, @@ -253,6 +260,20 @@ func resourceAwsCodeBuildProject() *schema.Resource { }, }, }, + + CustomizeDiff: customdiff.Sequence( + func(diff *schema.ResourceDiff, v interface{}) error { + // Plan time validation for cache location + cacheType, cacheTypeOk := diff.GetOk("cache.0.type") + if !cacheTypeOk || cacheType.(string) == codebuild.CacheTypeNoCache { + return nil + } + if v, ok := diff.GetOk("cache.0.location"); ok && v.(string) != "" { + return nil + } + return fmt.Errorf(`cache location is required when cache type is %q`, cacheType.(string)) + }, + ), } } @@ -366,8 +387,11 @@ func expandProjectCache(s []interface{}) *codebuild.ProjectCache { data := s[0].(map[string]interface{}) projectCache = &codebuild.ProjectCache{ - Type: aws.String(data["type"].(string)), - Location: aws.String(data["location"].(string)), + Type: aws.String(data["type"].(string)), + } + + if v, ok := data["location"]; ok { + projectCache.Location = aws.String(v.(string)) } return projectCache @@ -643,18 +667,13 @@ func flattenAwsCodeBuildProjectArtifacts(artifacts *codebuild.ProjectArtifacts) } func flattenAwsCodebuildProjectCache(cache *codebuild.ProjectCache) []interface{} { - values := map[string]interface{}{} - - if cache.Type != nil { - if *cache.Type == "NO_CACHE" { - values["type"] = "" - } else { - values["type"] = *cache.Type - } + if cache == nil { + return []interface{}{} } - if cache.Location != nil { - values["location"] = *cache.Location + values := map[string]interface{}{ + "location": aws.StringValue(cache.Location), + "type": aws.StringValue(cache.Type), } return []interface{}{values} diff --git a/aws/resource_aws_codebuild_project_test.go b/aws/resource_aws_codebuild_project_test.go index 2851b4964bc..62fbd1401b6 100644 --- a/aws/resource_aws_codebuild_project_test.go +++ b/aws/resource_aws_codebuild_project_test.go @@ -86,35 +86,50 @@ func TestAccAWSCodeBuildProject_cache(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckAWSCodeBuildProjectDestroy, Steps: []resource.TestStep{ + { + Config: testAccAWSCodeBuildProjectConfig_cache(name, testAccAWSCodeBuildProjectConfig_cacheConfig("S3", "")), + ExpectError: regexp.MustCompile(`cache location is required when cache type is "S3"`), + }, + { + Config: testAccAWSCodeBuildProjectConfig_cache(name, testAccAWSCodeBuildProjectConfig_cacheConfig("NO_CACHE", "")), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeBuildProjectExists("aws_codebuild_project.foo"), + resource.TestCheckResourceAttr("aws_codebuild_project.foo", "cache.#", "1"), + resource.TestCheckResourceAttr("aws_codebuild_project.foo", "cache.0.type", "NO_CACHE"), + ), + }, { Config: testAccAWSCodeBuildProjectConfig_cache(name, ""), Check: resource.ComposeTestCheckFunc( testAccCheckAWSCodeBuildProjectExists("aws_codebuild_project.foo"), - resource.TestCheckNoResourceAttr("aws_codebuild_project.foo", "cache"), + resource.TestCheckResourceAttr("aws_codebuild_project.foo", "cache.#", "1"), + resource.TestCheckResourceAttr("aws_codebuild_project.foo", "cache.0.type", "NO_CACHE"), ), }, { Config: testAccAWSCodeBuildProjectConfig_cache(name, testAccAWSCodeBuildProjectConfig_cacheConfig("S3", "some-bucket")), Check: resource.ComposeTestCheckFunc( testAccCheckAWSCodeBuildProjectExists("aws_codebuild_project.foo"), + resource.TestCheckResourceAttr("aws_codebuild_project.foo", "cache.#", "1"), resource.TestCheckResourceAttr("aws_codebuild_project.foo", "cache.0.type", "S3"), - resource.TestCheckResourceAttrSet("aws_codebuild_project.foo", "cache.0.location"), + resource.TestCheckResourceAttr("aws_codebuild_project.foo", "cache.0.location", "some-bucket"), ), }, { Config: testAccAWSCodeBuildProjectConfig_cache(name, testAccAWSCodeBuildProjectConfig_cacheConfig("S3", "some-new-bucket")), Check: resource.ComposeTestCheckFunc( testAccCheckAWSCodeBuildProjectExists("aws_codebuild_project.foo"), + resource.TestCheckResourceAttr("aws_codebuild_project.foo", "cache.#", "1"), resource.TestCheckResourceAttr("aws_codebuild_project.foo", "cache.0.type", "S3"), - resource.TestCheckResourceAttrSet("aws_codebuild_project.foo", "cache.0.location"), + resource.TestCheckResourceAttr("aws_codebuild_project.foo", "cache.0.location", "some-new-bucket"), ), }, { Config: testAccAWSCodeBuildProjectConfig_cache(name, ""), Check: resource.ComposeTestCheckFunc( testAccCheckAWSCodeBuildProjectExists("aws_codebuild_project.foo"), - resource.TestCheckResourceAttr("aws_codebuild_project.foo", "cache.0.type", "S3"), - resource.TestCheckResourceAttrSet("aws_codebuild_project.foo", "cache.0.location"), + resource.TestCheckResourceAttr("aws_codebuild_project.foo", "cache.#", "1"), + resource.TestCheckResourceAttr("aws_codebuild_project.foo", "cache.0.type", "NO_CACHE"), ), }, }, diff --git a/website/docs/r/codebuild_project.html.markdown b/website/docs/r/codebuild_project.html.markdown index b5d5f13aab4..3cf362d3b4f 100644 --- a/website/docs/r/codebuild_project.html.markdown +++ b/website/docs/r/codebuild_project.html.markdown @@ -151,8 +151,8 @@ The following arguments are supported: `cache` supports the following: -* `type` - (Required) The type of storage that will be used for the AWS CodeBuild project cache. The only valid value is `S3`. -* `location` - (Required) The location where the AWS CodeBuild project stores cached resources. This value must be a valid S3 bucket name/prefix. +* `type` - (Optional) The type of storage that will be used for the AWS CodeBuild project cache. Valid values: `NO_CACHE` and `S3`. Defaults to `NO_CACHE`. +* `location` - (Required when cache type is not `NO_CACHE`) The location where the AWS CodeBuild project stores cached resources. For type `S3` the value must be a valid S3 bucket name/prefix. `environment` supports the following: From 7664eef13385fcf2e0038d3374a97134479c97f9 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Wed, 11 Apr 2018 12:36:45 -0400 Subject: [PATCH 2/2] docs/resource/aws_codebuild_project: Adjust language surrounding when cache location argument is required --- website/docs/r/codebuild_project.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/codebuild_project.html.markdown b/website/docs/r/codebuild_project.html.markdown index 3cf362d3b4f..6392a721cd4 100644 --- a/website/docs/r/codebuild_project.html.markdown +++ b/website/docs/r/codebuild_project.html.markdown @@ -152,7 +152,7 @@ The following arguments are supported: `cache` supports the following: * `type` - (Optional) The type of storage that will be used for the AWS CodeBuild project cache. Valid values: `NO_CACHE` and `S3`. Defaults to `NO_CACHE`. -* `location` - (Required when cache type is not `NO_CACHE`) The location where the AWS CodeBuild project stores cached resources. For type `S3` the value must be a valid S3 bucket name/prefix. +* `location` - (Required when cache type is `S3`) The location where the AWS CodeBuild project stores cached resources. For type `S3` the value must be a valid S3 bucket name/prefix. `environment` supports the following: