From 1f947afac9e2d04b3ec13f229425f34f8c66d88e Mon Sep 17 00:00:00 2001 From: mrinalirao Date: Wed, 16 Nov 2022 11:13:51 +1100 Subject: [PATCH 1/6] Add OPA support for policy sets --- go.mod | 2 +- go.sum | 4 +- tfe/data_source_policy_set.go | 21 +++++++++ tfe/data_source_policy_set_test.go | 70 +++++++++++++++++++++++++++++ tfe/resource_tfe_policy_set.go | 30 +++++++++++++ tfe/resource_tfe_policy_set_test.go | 48 ++++++++++++++++++++ 6 files changed, 172 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f2f6cd2ed..686c7e55a 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.1 // indirect github.com/hashicorp/go-slug v0.10.0 - github.com/hashicorp/go-tfe v1.12.0 + github.com/hashicorp/go-tfe v1.13.0 github.com/hashicorp/go-version v1.6.0 github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce github.com/hashicorp/hcl/v2 v2.15.0 // indirect diff --git a/go.sum b/go.sum index f16d31ba1..380b30b4d 100644 --- a/go.sum +++ b/go.sum @@ -163,8 +163,8 @@ github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1 github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-slug v0.10.0 h1:mh4DDkBJTh9BuEjY/cv8PTo7k9OjT4PcW8PgZnJ4jTY= github.com/hashicorp/go-slug v0.10.0/go.mod h1:Ib+IWBYfEfJGI1ZyXMGNbu2BU+aa3Dzu41RKLH301v4= -github.com/hashicorp/go-tfe v1.12.0 h1:2l7emKW8rNTTbnxYHNVj6b46iJzOEp2G/3xIHfGSDnc= -github.com/hashicorp/go-tfe v1.12.0/go.mod h1:thYtIxtgBpDDNdf/2yYPdBJ94Fz5yT5XCNZvGtTGHAU= +github.com/hashicorp/go-tfe v1.13.0 h1:Z8pJrmN9BV5EncnFRmQmLjhP7pHMNXkC2VkCQXWxKjM= +github.com/hashicorp/go-tfe v1.13.0/go.mod h1:thYtIxtgBpDDNdf/2yYPdBJ94Fz5yT5XCNZvGtTGHAU= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= diff --git a/tfe/data_source_policy_set.go b/tfe/data_source_policy_set.go index 5c8625993..1e2810cd6 100644 --- a/tfe/data_source_policy_set.go +++ b/tfe/data_source_policy_set.go @@ -33,6 +33,18 @@ func dataSourceTFEPolicySet() *schema.Resource { Computed: true, }, + "kind": { + Type: schema.TypeString, + Optional: true, + Default: string(tfe.Sentinel), + }, + + "overridable": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "policies_path": { Type: schema.TypeString, Computed: true, @@ -100,6 +112,7 @@ func dataSourceTFEPolicySetRead(d *schema.ResourceData, meta interface{}) error } for _, policySet := range policySetList.Items { + // nolint: nestif if policySet.Name == name { d.Set("name", policySet.Name) d.Set("description", policySet.Description) @@ -110,6 +123,14 @@ func dataSourceTFEPolicySetRead(d *schema.ResourceData, meta interface{}) error d.Set("organization", policySet.Organization.Name) } + if policySet.Kind != "" { + d.Set("kind", policySet.Kind) + } + + if policySet.Overridable != nil { + d.Set("overridable", policySet.Overridable) + } + var vcsRepo []interface{} if policySet.VCSRepo != nil { vcsRepo = append(vcsRepo, map[string]interface{}{ diff --git a/tfe/data_source_policy_set_test.go b/tfe/data_source_policy_set_test.go index cdc92eb5b..b0277a573 100644 --- a/tfe/data_source_policy_set_test.go +++ b/tfe/data_source_policy_set_test.go @@ -50,6 +50,49 @@ func TestAccTFEPolicySetDataSource_basic(t *testing.T) { ) } +func TestAccTFEPolicySetDataSourceOPA_basic(t *testing.T) { + skipUnlessBeta(t) + tfeClient, err := getClientUsingEnv() + if err != nil { + t.Fatal(err) + } + + org, orgCleanup := createBusinessOrganization(t, tfeClient) + t.Cleanup(orgCleanup) + + rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccTFEPolicySetDataSourceConfigOPA_basic(org.Name, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("data.tfe_policy_set.bar", "id"), + resource.TestCheckResourceAttr( + "data.tfe_policy_set.bar", "name", fmt.Sprintf("tst-policy-set-%d", rInt)), + resource.TestCheckResourceAttr( + "data.tfe_policy_set.bar", "description", "Policy Set"), + resource.TestCheckResourceAttr( + "data.tfe_policy_set.bar", "global", "false"), + resource.TestCheckResourceAttr( + "data.tfe_policy_set.bar", "organization", org.Name), + resource.TestCheckResourceAttr( + "data.tfe_policy_set.bar", "kind", "opa"), + resource.TestCheckResourceAttr( + "data.tfe_policy_set.bar", "overridable", "true"), + resource.TestCheckResourceAttr( + "data.tfe_policy_set.bar", "workspace_ids.#", "1"), + resource.TestCheckResourceAttr( + "data.tfe_policy_set.bar", "vcs_repo.#", "0"), + ), + }, + }, + }, + ) +} + func TestAccTFEPolicySetDataSource_vcs(t *testing.T) { tfeClient, err := getClientUsingEnv() if err != nil { @@ -152,6 +195,33 @@ data "tfe_policy_set" "bar" { }`, organization, rInt, rInt) } +func testAccTFEPolicySetDataSourceConfigOPA_basic(organization string, rInt int) string { + return fmt.Sprintf(` +locals { + organization_name = "%s" +} + +resource "tfe_workspace" "foobar" { + name = "workspace-foo-%d" + organization = local.organization_name +} + +resource "tfe_policy_set" "foobar" { + name = "tst-policy-set-%d" + description = "Policy Set" + organization = local.organization_name + kind = "opa" + overridable = true + workspace_ids = [tfe_workspace.foobar.id] +} + +data "tfe_policy_set" "bar" { + name = tfe_policy_set.foobar.name + organization = local.organization_name + kind = "opa" +}`, organization, rInt, rInt) +} + func testAccTFEPolicySetDataSourceConfig_vcs(organization string, rInt int) string { return fmt.Sprintf(` locals { diff --git a/tfe/resource_tfe_policy_set.go b/tfe/resource_tfe_policy_set.go index 5cfe590d4..428fa4b71 100644 --- a/tfe/resource_tfe_policy_set.go +++ b/tfe/resource_tfe_policy_set.go @@ -46,6 +46,23 @@ func resourceTFEPolicySet() *schema.Resource { ConflictsWith: []string{"workspace_ids"}, }, + "kind": { + Type: schema.TypeString, + Optional: true, + Default: string(tfe.Sentinel), + ValidateFunc: validation.StringInSlice( + []string{ + string(tfe.OPA), + string(tfe.Sentinel), + }, false), + }, + + "overridable": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "policies_path": { Type: schema.TypeString, Optional: true, @@ -123,6 +140,14 @@ func resourceTFEPolicySetCreate(d *schema.ResourceData, meta interface{}) error } // Process all configured options. + if vKind, ok := d.GetOk("kind"); ok { + options.Kind = tfe.PolicyKind(vKind.(string)) + } + + if vOverridable, ok := d.GetOk("overridable"); ok { + options.Overridable = tfe.Bool(vOverridable.(bool)) + } + if desc, ok := d.GetOk("description"); ok { options.Description = tfe.String(desc.(string)) } @@ -192,6 +217,7 @@ func resourceTFEPolicySetRead(d *schema.ResourceData, meta interface{}) error { // Update the config. d.Set("name", policySet.Name) d.Set("description", policySet.Description) + d.Set("kind", policySet.Kind) d.Set("global", policySet.Global) d.Set("policies_path", policySet.PoliciesPath) @@ -199,6 +225,10 @@ func resourceTFEPolicySetRead(d *schema.ResourceData, meta interface{}) error { d.Set("organization", policySet.Organization.Name) } + if policySet.Overridable != nil { + d.Set("overridable", policySet.Overridable) + } + // Set VCS policy set options. var vcsRepo []interface{} if policySet.VCSRepo != nil { diff --git a/tfe/resource_tfe_policy_set_test.go b/tfe/resource_tfe_policy_set_test.go index 08e6a66d0..6da992ed9 100644 --- a/tfe/resource_tfe_policy_set_test.go +++ b/tfe/resource_tfe_policy_set_test.go @@ -46,6 +46,44 @@ func TestAccTFEPolicySet_basic(t *testing.T) { }) } +func TestAccTFEPolicySetOPA_basic(t *testing.T) { + skipUnlessBeta(t) + tfeClient, err := getClientUsingEnv() + if err != nil { + t.Fatal(err) + } + + org, orgCleanup := createBusinessOrganization(t, tfeClient) + t.Cleanup(orgCleanup) + + policySet := &tfe.PolicySet{} + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckTFEPolicySetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTFEPolicySetOPA_basic(org.Name), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEPolicySetExists("tfe_policy_set.foobar", policySet), + testAccCheckTFEPolicySetAttributes(policySet), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "name", "tst-terraform"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "kind", "opa"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "overridable", "false"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "description", "Policy Set"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "global", "false"), + ), + }, + }, + }) +} + func TestAccTFEPolicySet_update(t *testing.T) { tfeClient, err := getClientUsingEnv() if err != nil { @@ -819,6 +857,16 @@ resource "tfe_policy_set" "foobar" { }`, organization, organization) } +func testAccTFEPolicySetOPA_basic(organization string) string { + return fmt.Sprintf(` +resource "tfe_policy_set" "foobar" { + name = "tst-terraform" + description = "Policy Set" + organization = "%s" + kind = "opa" +}`, organization) +} + func testAccTFEPolicySet_empty(organization string) string { return fmt.Sprintf(` resource "tfe_policy_set" "foobar" { From 6c01d2202193333d7ad51f3bf072a66db0f2f358 Mon Sep 17 00:00:00 2001 From: mrinalirao Date: Wed, 16 Nov 2022 11:28:50 +1100 Subject: [PATCH 2/6] add CHANGELOG.md and fix broken tests --- CHANGELOG.md | 2 ++ tfe/data_source_policy_set.go | 1 - tfe/data_source_policy_set_test.go | 2 ++ tfe/resource_tfe_policy_set.go | 6 +++++- tfe/resource_tfe_policy_set_test.go | 15 +++++++++++++++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b74267e0f..651dbdef8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ FEATURES: * r/tfe_organization: Add `allow_force_delete_workspaces` attribute to set whether admins are permitted to delete workspaces with resource under management. ([#661](https://github.com/hashicorp/terraform-provider-tfe/pull/661)) +* r/tfe_policy_set: Add OPA support for policy sets. ([#691](https://github.com/hashicorp/terraform-provider-tfe/pull/691)) +* d/tfe_policy_set: Add optional `kind` and `overridable` fields for OPA policy sets ([#691](https://github.com/hashicorp/terraform-provider-tfe/pull/691)) ## v0.38.0 (October 24, 2022) diff --git a/tfe/data_source_policy_set.go b/tfe/data_source_policy_set.go index 1e2810cd6..db73fc344 100644 --- a/tfe/data_source_policy_set.go +++ b/tfe/data_source_policy_set.go @@ -36,7 +36,6 @@ func dataSourceTFEPolicySet() *schema.Resource { "kind": { Type: schema.TypeString, Optional: true, - Default: string(tfe.Sentinel), }, "overridable": { diff --git a/tfe/data_source_policy_set_test.go b/tfe/data_source_policy_set_test.go index b0277a573..760cd9b65 100644 --- a/tfe/data_source_policy_set_test.go +++ b/tfe/data_source_policy_set_test.go @@ -133,6 +133,8 @@ func TestAccTFEPolicySetDataSource_vcs(t *testing.T) { "data.tfe_policy_set.bar", "description", "Policy Set"), resource.TestCheckResourceAttr( "data.tfe_policy_set.bar", "global", "false"), + resource.TestCheckResourceAttr( + "data.tfe_policy_set.bar", "kind", "sentinel"), resource.TestCheckResourceAttr( "data.tfe_policy_set.bar", "organization", org.Name), resource.TestCheckResourceAttr( diff --git a/tfe/resource_tfe_policy_set.go b/tfe/resource_tfe_policy_set.go index 428fa4b71..82c6929b3 100644 --- a/tfe/resource_tfe_policy_set.go +++ b/tfe/resource_tfe_policy_set.go @@ -217,7 +217,6 @@ func resourceTFEPolicySetRead(d *schema.ResourceData, meta interface{}) error { // Update the config. d.Set("name", policySet.Name) d.Set("description", policySet.Description) - d.Set("kind", policySet.Kind) d.Set("global", policySet.Global) d.Set("policies_path", policySet.PoliciesPath) @@ -225,6 +224,11 @@ func resourceTFEPolicySetRead(d *schema.ResourceData, meta interface{}) error { d.Set("organization", policySet.Organization.Name) } + // Note: Old API endpoints return an empty string, so use the default in the schema + if policySet.Kind != "" { + d.Set("kind", policySet.Kind) + } + if policySet.Overridable != nil { d.Set("overridable", policySet.Overridable) } diff --git a/tfe/resource_tfe_policy_set_test.go b/tfe/resource_tfe_policy_set_test.go index 6da992ed9..fe8169462 100644 --- a/tfe/resource_tfe_policy_set_test.go +++ b/tfe/resource_tfe_policy_set_test.go @@ -125,6 +125,8 @@ func TestAccTFEPolicySet_update(t *testing.T) { "tfe_policy_set.foobar", "name", "terraform-populated"), resource.TestCheckResourceAttr( "tfe_policy_set.foobar", "global", "false"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "kind", "sentinel"), resource.TestCheckResourceAttr( "tfe_policy_set.foobar", "policy_ids.#", "1"), resource.TestCheckResourceAttr( @@ -227,6 +229,8 @@ func TestAccTFEPolicySet_updatePopulated(t *testing.T) { "tfe_policy_set.foobar", "name", "terraform-populated-updated"), resource.TestCheckResourceAttr( "tfe_policy_set.foobar", "global", "false"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "kind", "sentinel"), resource.TestCheckResourceAttr( "tfe_policy_set.foobar", "policy_ids.#", "1"), resource.TestCheckResourceAttr( @@ -278,6 +282,8 @@ func TestAccTFEPolicySet_updateToGlobal(t *testing.T) { "tfe_policy_set.foobar", "name", "terraform-global"), resource.TestCheckResourceAttr( "tfe_policy_set.foobar", "global", "true"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "kind", "sentinel"), resource.TestCheckResourceAttr( "tfe_policy_set.foobar", "policy_ids.#", "1"), ), @@ -376,6 +382,8 @@ func TestAccTFEPolicySet_vcs(t *testing.T) { "tfe_policy_set.foobar", "description", "Policy Set"), resource.TestCheckResourceAttr( "tfe_policy_set.foobar", "global", "false"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "kind", "sentinel"), resource.TestCheckResourceAttr( "tfe_policy_set.foobar", "vcs_repo.0.identifier", GITHUB_POLICY_SET_IDENTIFIER), resource.TestCheckResourceAttr( @@ -431,6 +439,8 @@ func TestAccTFEPolicySet_updateVCSBranch(t *testing.T) { "tfe_policy_set.foobar", "description", "Policy Set"), resource.TestCheckResourceAttr( "tfe_policy_set.foobar", "global", "false"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "kind", "sentinel"), resource.TestCheckResourceAttr( "tfe_policy_set.foobar", "vcs_repo.0.identifier", GITHUB_POLICY_SET_IDENTIFIER), resource.TestCheckResourceAttr( @@ -453,6 +463,8 @@ func TestAccTFEPolicySet_updateVCSBranch(t *testing.T) { "tfe_policy_set.foobar", "description", "Policy Set"), resource.TestCheckResourceAttr( "tfe_policy_set.foobar", "global", "false"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "kind", "sentinel"), resource.TestCheckResourceAttr( "tfe_policy_set.foobar", "vcs_repo.0.identifier", GITHUB_POLICY_SET_IDENTIFIER), resource.TestCheckResourceAttr( @@ -666,6 +678,9 @@ func TestAccTFEPolicySetImport(t *testing.T) { ResourceName: "tfe_policy_set.foobar", ImportState: true, ImportStateVerify: true, + // Note: We ignore the optional fields below, since the old API endpoints send empty values + // and the results may vary depending on the API version + ImportStateVerifyIgnore: []string{"kind", "overridable"}, }, }, }) From f5b76e54cf95d35e6288a4f77b7b55ebd6d35115 Mon Sep 17 00:00:00 2001 From: mrinalirao Date: Thu, 17 Nov 2022 12:20:02 +1100 Subject: [PATCH 3/6] add descriptions to fields --- tfe/data_source_policy_set.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tfe/data_source_policy_set.go b/tfe/data_source_policy_set.go index db73fc344..62bdf8f4c 100644 --- a/tfe/data_source_policy_set.go +++ b/tfe/data_source_policy_set.go @@ -34,14 +34,16 @@ func dataSourceTFEPolicySet() *schema.Resource { }, "kind": { - Type: schema.TypeString, - Optional: true, + Description: "The policy-as-code framework for the policy. Valid values are sentinel and opa", + Type: schema.TypeString, + Optional: true, }, "overridable": { - Type: schema.TypeBool, - Optional: true, - Default: false, + Description: "Whether users can override this policy when it fails during a run. Only valid for OPA policies", + Type: schema.TypeBool, + Optional: true, + Default: false, }, "policies_path": { From 9e1f8440f8b0cc3aededa662a06a44d6ee03625f Mon Sep 17 00:00:00 2001 From: mrinalirao Date: Fri, 18 Nov 2022 10:58:03 +1100 Subject: [PATCH 4/6] add ForceNew to kind attribute --- tfe/resource_tfe_policy_set.go | 1 + 1 file changed, 1 insertion(+) diff --git a/tfe/resource_tfe_policy_set.go b/tfe/resource_tfe_policy_set.go index 82c6929b3..e89d10256 100644 --- a/tfe/resource_tfe_policy_set.go +++ b/tfe/resource_tfe_policy_set.go @@ -50,6 +50,7 @@ func resourceTFEPolicySet() *schema.Resource { Type: schema.TypeString, Optional: true, Default: string(tfe.Sentinel), + ForceNew: true, ValidateFunc: validation.StringInSlice( []string{ string(tfe.OPA), From 56bffac6dd3a2dc6b99b7e22c98a27e185fddec3 Mon Sep 17 00:00:00 2001 From: mrinalirao Date: Thu, 24 Nov 2022 10:17:50 +1100 Subject: [PATCH 5/6] remove default from datasource --- tfe/data_source_policy_set.go | 1 - 1 file changed, 1 deletion(-) diff --git a/tfe/data_source_policy_set.go b/tfe/data_source_policy_set.go index 62bdf8f4c..e827671e3 100644 --- a/tfe/data_source_policy_set.go +++ b/tfe/data_source_policy_set.go @@ -43,7 +43,6 @@ func dataSourceTFEPolicySet() *schema.Resource { Description: "Whether users can override this policy when it fails during a run. Only valid for OPA policies", Type: schema.TypeBool, Optional: true, - Default: false, }, "policies_path": { From 4f5c441e70024afd10df53c45845eb21d1b00714 Mon Sep 17 00:00:00 2001 From: mrinalirao Date: Tue, 29 Nov 2022 09:33:38 +1100 Subject: [PATCH 6/6] update overridable if set --- go.mod | 4 +- go.sum | 8 +-- tfe/resource_tfe_policy_set.go | 7 ++- tfe/resource_tfe_policy_set_test.go | 76 +++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 686c7e55a..20c2074ce 100644 --- a/go.mod +++ b/go.mod @@ -11,8 +11,8 @@ require ( github.com/hashicorp/go-hclog v1.2.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.1 // indirect - github.com/hashicorp/go-slug v0.10.0 - github.com/hashicorp/go-tfe v1.13.0 + github.com/hashicorp/go-slug v0.10.1 + github.com/hashicorp/go-tfe v1.14.0 github.com/hashicorp/go-version v1.6.0 github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce github.com/hashicorp/hcl/v2 v2.15.0 // indirect diff --git a/go.sum b/go.sum index 380b30b4d..45194ecf1 100644 --- a/go.sum +++ b/go.sum @@ -161,10 +161,10 @@ github.com/hashicorp/go-plugin v1.4.6 h1:MDV3UrKQBM3du3G7MApDGvOsMYy3JQJ4exhSoKB github.com/hashicorp/go-plugin v1.4.6/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ= github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-slug v0.10.0 h1:mh4DDkBJTh9BuEjY/cv8PTo7k9OjT4PcW8PgZnJ4jTY= -github.com/hashicorp/go-slug v0.10.0/go.mod h1:Ib+IWBYfEfJGI1ZyXMGNbu2BU+aa3Dzu41RKLH301v4= -github.com/hashicorp/go-tfe v1.13.0 h1:Z8pJrmN9BV5EncnFRmQmLjhP7pHMNXkC2VkCQXWxKjM= -github.com/hashicorp/go-tfe v1.13.0/go.mod h1:thYtIxtgBpDDNdf/2yYPdBJ94Fz5yT5XCNZvGtTGHAU= +github.com/hashicorp/go-slug v0.10.1 h1:05SCRWCBpCxOeP7stQHvMgOz0raCBCekaytu8Rg/RZ4= +github.com/hashicorp/go-slug v0.10.1/go.mod h1:Ib+IWBYfEfJGI1ZyXMGNbu2BU+aa3Dzu41RKLH301v4= +github.com/hashicorp/go-tfe v1.14.0 h1:FZKKkwlyTxw8/OE3e7NiFQLcgGXTHra9ogGhMTotxh8= +github.com/hashicorp/go-tfe v1.14.0/go.mod h1:77snluBqtTTvMrY0w/mxQA5jlHQ8NT44AqQ8UdrPf0o= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= diff --git a/tfe/resource_tfe_policy_set.go b/tfe/resource_tfe_policy_set.go index e89d10256..2bfb5260d 100644 --- a/tfe/resource_tfe_policy_set.go +++ b/tfe/resource_tfe_policy_set.go @@ -306,7 +306,7 @@ func resourceTFEPolicySetUpdate(d *schema.ResourceData, meta interface{}) error } // Don't bother updating the policy set's attributes if they haven't changed - if d.HasChange("name") || d.HasChange("description") || d.HasChange("global") || d.HasChange("vcs_repo") { + if d.HasChange("name") || d.HasChange("description") || d.HasChange("global") || d.HasChange("vcs_repo") || d.HasChange("overridable") { // Create a new options struct. options := tfe.PolicySetUpdateOptions{ Name: tfe.String(name), @@ -317,6 +317,11 @@ func resourceTFEPolicySetUpdate(d *schema.ResourceData, meta interface{}) error options.Description = tfe.String(desc.(string)) } + if d.HasChange("overridable") { + o := d.Get("overridable").(bool) + options.Overridable = tfe.Bool(o) + } + if v, ok := d.GetOk("vcs_repo"); ok { vcsRepo := v.([]interface{})[0].(map[string]interface{}) diff --git a/tfe/resource_tfe_policy_set_test.go b/tfe/resource_tfe_policy_set_test.go index fe8169462..b6a88cd3b 100644 --- a/tfe/resource_tfe_policy_set_test.go +++ b/tfe/resource_tfe_policy_set_test.go @@ -84,6 +84,61 @@ func TestAccTFEPolicySetOPA_basic(t *testing.T) { }) } +func TestAccTFEPolicySet_updateOverridable(t *testing.T) { + skipUnlessBeta(t) + tfeClient, err := getClientUsingEnv() + if err != nil { + t.Fatal(err) + } + + org, orgCleanup := createBusinessOrganization(t, tfeClient) + t.Cleanup(orgCleanup) + + policySet := &tfe.PolicySet{} + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckTFEPolicySetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTFEPolicySetOPA_basic(org.Name), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEPolicySetExists("tfe_policy_set.foobar", policySet), + testAccCheckTFEPolicySetAttributes(policySet), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "name", "tst-terraform"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "description", "Policy Set"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "kind", "opa"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "global", "false"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "overridable", "true"), + ), + }, + + { + Config: testAccTFEPolicySetOPA_overridable(org.Name), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEPolicySetExists("tfe_policy_set.foobar", policySet), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "name", "tst-terraform"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "global", "false"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "kind", "opa"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "workspace_ids.#", "1"), + resource.TestCheckResourceAttr( + "tfe_policy_set.foobar", "overridable", "false"), + ), + }, + }, + }) +} + func TestAccTFEPolicySet_update(t *testing.T) { tfeClient, err := getClientUsingEnv() if err != nil { @@ -879,6 +934,7 @@ resource "tfe_policy_set" "foobar" { description = "Policy Set" organization = "%s" kind = "opa" + overridable = "true" }`, organization) } @@ -916,6 +972,26 @@ resource "tfe_policy_set" "foobar" { }`, organization) } +func testAccTFEPolicySetOPA_overridable(organization string) string { + return fmt.Sprintf(` +locals { + organization_name = "%s" +} + +resource "tfe_workspace" "foo" { + name = "workspace-foo" + organization = local.organization_name +} + +resource "tfe_policy_set" "foobar" { + name = "tst-terraform" + organization = local.organization_name + workspace_ids = [tfe_workspace.foo.id] + overridable = "false" + kind = "opa" +}`, organization) +} + func testAccTFEPolicySet_updatePopulated(organization string) string { return fmt.Sprintf(` locals {