Skip to content

Commit

Permalink
Merged automatically by CI pipeline
Browse files Browse the repository at this point in the history
SCALRCORE-28980 API > Policy Engine > Enforce policy group for all cu…
  • Loading branch information
emocharnik authored Nov 27, 2023
2 parents c357edb + a953f1e commit 13fe246
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 18 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- `scalr_policy_group`: `environments` attribute became optional instead of read-only ([#288](https://github.com/Scalr/terraform-provider-scalr/pull/288))

## [1.6.0] - 2023-10-27

### Added
Expand Down
2 changes: 1 addition & 1 deletion docs/resources/policy_group.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ resource "scalr_policy_group" "example" {
### Optional

- `account_id` (String) The identifier of the Scalr account, in the format `acc-<RANDOM STRING>`.
- `environments` (List of String) A list of the environments the policy group is linked to. Use `["*"]` to enforce in all environments.
- `opa_version` (String) The version of Open Policy Agent to run policies against. If omitted, the system default version is assigned.

### Read-Only

- `environments` (List of String) A list of the environments the policy group is linked to.
- `error_message` (String) A detailed error if Scalr failed to process the policy group.
- `id` (String) The ID of this resource.
- `policies` (List of Object) A list of the OPA policies the group verifies each run. (see [below for nested schema](#nestedatt--policies))
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/hashicorp/terraform-plugin-docs v0.16.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734
github.com/scalr/go-scalr v0.0.0-20231004160327-c0bbb43d3b4f
github.com/scalr/go-scalr v0.0.0-20231117090940-913594e4e135
)

require (
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
github.com/scalr/go-scalr v0.0.0-20231004160327-c0bbb43d3b4f h1:2acK1M8YNfTe1rpn9UUhR0UIGMWCmHw4BMxQCCM7lPo=
github.com/scalr/go-scalr v0.0.0-20231004160327-c0bbb43d3b4f/go.mod h1:p34SHb25YRvbgft7SUjSDYESeoQhWzAlxGXId/BbaSE=
github.com/scalr/go-scalr v0.0.0-20231117090940-913594e4e135 h1:EAfMV+rwOLld3pJPwUnrFRyt3jxYx/N0q+fjextco0s=
github.com/scalr/go-scalr v0.0.0-20231117090940-913594e4e135/go.mod h1:p34SHb25YRvbgft7SUjSDYESeoQhWzAlxGXId/BbaSE=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
Expand Down
10 changes: 6 additions & 4 deletions scalr/data_source_scalr_policy_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func dataSourceScalrPolicyGroup() *schema.Resource {
},
},
"environments": {
Description: "A list of the environments the policy group is linked to.",
Description: "A list of the environments the policy group is linked to, or `[\"*\"]` if enforced in all environments.",
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Expand Down Expand Up @@ -183,13 +183,15 @@ func dataSourceScalrPolicyGroupRead(ctx context.Context, d *schema.ResourceData,
}
_ = d.Set("policies", policies)

var envs []string
if len(pg.Environments) != 0 {
if pg.IsEnforced {
_ = d.Set("environments", []string{"*"})
} else {
envs := make([]string, 0)
for _, env := range pg.Environments {
envs = append(envs, env.ID)
}
_ = d.Set("environments", envs)
}
_ = d.Set("environments", envs)

d.SetId(pg.ID)

Expand Down
94 changes: 84 additions & 10 deletions scalr/resource_scalr_policy_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import (
"context"
"errors"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"log"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/scalr/go-scalr"
"log"
)

func resourceScalrPolicyGroup() *schema.Resource {
Expand Down Expand Up @@ -108,9 +107,9 @@ func resourceScalrPolicyGroup() *schema.Resource {
},
},
"environments": {
Description: "A list of the environments the policy group is linked to.",
Description: "A list of the environments the policy group is linked to. Use `[\"*\"]` to enforce in all environments.",
Type: schema.TypeList,
Computed: true,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
Expand Down Expand Up @@ -141,6 +140,24 @@ func resourceScalrPolicyGroupCreate(ctx context.Context, d *schema.ResourceData,
VCSRepo: vcsOpt,
Account: &scalr.Account{ID: accountID},
VcsProvider: &scalr.VcsProvider{ID: vcsProviderID},
IsEnforced: scalr.Bool(false),
}

environments := make([]*scalr.Environment, 0)
if environmentsI, ok := d.GetOk("environments"); ok {
environmentsIDs := environmentsI.([]interface{})
if (len(environmentsIDs) == 1) && environmentsIDs[0].(string) == "*" {
opts.IsEnforced = scalr.Bool(true)
} else if len(environmentsIDs) > 0 {
for _, env := range environmentsIDs {
if env.(string) == "*" {
return diag.Errorf(
"impossible to enforce the policy group in all and on a limited list of environments. Please remove either wildcard or environment identifiers",
)
}
environments = append(environments, &scalr.Environment{ID: env.(string)})
}
}
}

// Optional attributes
Expand All @@ -154,6 +171,25 @@ func resourceScalrPolicyGroupCreate(ctx context.Context, d *schema.ResourceData,
}

d.SetId(pg.ID)

if len(environments) > 0 && !*opts.IsEnforced {
pgEnvs := make([]*scalr.PolicyGroupEnvironment, 0)
for _, env := range environments {
pgEnvs = append(pgEnvs, &scalr.PolicyGroupEnvironment{ID: env.ID})
}
pgEnvsOpts := scalr.PolicyGroupEnvironmentsCreateOptions{
PolicyGroupID: pg.ID,
PolicyGroupEnvironments: pgEnvs,
}
err = scalrClient.PolicyGroupEnvironments.Create(ctx, pgEnvsOpts)
if err != nil {
defer func(ctx context.Context, pgID string) {
_ = scalrClient.PolicyGroups.Delete(ctx, pgID)
}(ctx, pg.ID)
return diag.Errorf("error linking environments to policy group '%s': %v", name, err)
}
}

return resourceScalrPolicyGroupRead(ctx, d, meta)
}

Expand Down Expand Up @@ -197,13 +233,16 @@ func resourceScalrPolicyGroupRead(ctx context.Context, d *schema.ResourceData, m
}
_ = d.Set("policies", policies)

var envs []string
if len(pg.Environments) != 0 {
for _, env := range pg.Environments {
envs = append(envs, env.ID)
if pg.IsEnforced {
allEnvironments := []string{"*"}
_ = d.Set("environments", allEnvironments)
} else {
environmentIDs := make([]string, 0)
for _, environment := range pg.Environments {
environmentIDs = append(environmentIDs, environment.ID)
}
_ = d.Set("environments", environmentIDs)
}
_ = d.Set("environments", envs)

return nil
}
Expand All @@ -214,7 +253,8 @@ func resourceScalrPolicyGroupUpdate(ctx context.Context, d *schema.ResourceData,
id := d.Id()

if d.HasChange("name") || d.HasChange("opa_version") ||
d.HasChange("vcs_provider_id") || d.HasChange("vcs_repo") {
d.HasChange("vcs_provider_id") || d.HasChange("vcs_repo") ||
d.HasChange("environments") {

name := d.Get("name").(string)
vcsProviderID := d.Get("vcs_provider_id").(string)
Expand All @@ -234,16 +274,50 @@ func resourceScalrPolicyGroupUpdate(ctx context.Context, d *schema.ResourceData,
Name: scalr.String(name),
VCSRepo: vcsOpt,
VcsProvider: &scalr.VcsProvider{ID: vcsProviderID},
IsEnforced: scalr.Bool(false),
}
if opaVersion, ok := d.GetOk("opa_version"); ok {
opts.OpaVersion = scalr.String(opaVersion.(string))
}

environments := make([]*scalr.Environment, 0)
if environmentsI, ok := d.GetOk("environments"); ok {
environmentsIDs := environmentsI.([]interface{})
if (len(environmentsIDs) == 1) && environmentsIDs[0].(string) == "*" {
opts.IsEnforced = scalr.Bool(true)
} else if len(environmentsIDs) > 0 {
for _, env := range environmentsIDs {
if env.(string) == "*" {
return diag.Errorf(
"impossible to enforce the policy group in all and on a limited list of environments. Please remove either wildcard or environment identifiers",
)
}
environments = append(environments, &scalr.Environment{ID: env.(string)})
}
}
}

log.Printf("[DEBUG] Update policy group %s", id)
_, err := scalrClient.PolicyGroups.Update(ctx, id, opts)
if err != nil {
return diag.Errorf("error updating policy group %s: %v", id, err)
}

if !*opts.IsEnforced {
pgEnvs := make([]*scalr.PolicyGroupEnvironment, 0)
for _, env := range environments {
pgEnvs = append(pgEnvs, &scalr.PolicyGroupEnvironment{ID: env.ID})
}
pgEnvsOpts := scalr.PolicyGroupEnvironmentsUpdateOptions{
PolicyGroupID: id,
PolicyGroupEnvironments: pgEnvs,
}

err = scalrClient.PolicyGroupEnvironments.Update(ctx, pgEnvsOpts)
if err != nil {
return diag.Errorf("error updating environments for policy group %s: %v", id, err)
}
}
}

return resourceScalrPolicyGroupRead(ctx, d, meta)
Expand Down

0 comments on commit 13fe246

Please sign in to comment.