Skip to content

Commit

Permalink
Merge pull request #584 from hashicorp/mr/TF-1450-policy-override
Browse files Browse the repository at this point in the history
Add OPA support for task stages
  • Loading branch information
mrinalirao committed Nov 14, 2022
2 parents 7a3cfda + 34922c8 commit 0f28f32
Show file tree
Hide file tree
Showing 8 changed files with 441 additions and 30 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -9,6 +9,7 @@
* Add OPA support to the Policy Set APIs by @mrinalirao [#575](https://github.com/hashicorp/go-tfe/pull/575)
* Add OPA support to the Policy APIs by @mrinalirao [#579](https://github.com/hashicorp/go-tfe/pull/579)
* Add Policy Evaluation and Policy Set Outcome APIs by @mrinalirao [#583](https://github.com/hashicorp/go-tfe/pull/583)
* Add OPA support to Task Stage APIs by @mrinalirao [#584](https://github.com/hashicorp/go-tfe/pull/584)

# v1.12.0

Expand Down
30 changes: 30 additions & 0 deletions helper_test.go
Expand Up @@ -556,6 +556,36 @@ func createPolicySet(t *testing.T, client *Client, org *Organization, policies [
}
}

func createPolicySetWithOptions(t *testing.T, client *Client, org *Organization, policies []*Policy, workspaces []*Workspace, opts PolicySetCreateOptions) (*PolicySet, func()) {
var orgCleanup func()

if org == nil {
org, orgCleanup = createOrganization(t, client)
}

ctx := context.Background()
ps, err := client.PolicySets.Create(ctx, org.Name, PolicySetCreateOptions{
Name: String(randomString(t)),
Policies: policies,
Workspaces: workspaces,
Kind: opts.Kind,
Overridable: opts.Overridable,
})
if err != nil {
t.Fatal(err)
}
return ps, func() {
if err := client.PolicySets.Delete(ctx, ps.ID); err != nil {
t.Errorf("Error destroying policy set! WARNING: Dangling resources\n"+
"may exist! The full error is shown below.\n\n"+
"PolicySet: %s\nError: %s", ps.ID, err)
}
if orgCleanup != nil {
orgCleanup()
}
}
}

func createPolicySetVersion(t *testing.T, client *Client, ps *PolicySet) (*PolicySetVersion, func()) {
var psCleanup func()

Expand Down
15 changes: 15 additions & 0 deletions mocks/task_stages_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions policy_integration_beta_test.go
Expand Up @@ -235,10 +235,9 @@ func TestPoliciesList_Beta(t *testing.T) {
defer pTestCleanup2()
opaOptions := PolicyCreateOptions{
Kind: OPA,
Query: String("terraform.policy1.deny"),
Query: String("data.example.rule"),
Enforce: []*EnforcementOptions{
{
Path: String(".rego"),
Mode: EnforcementMode(EnforcementMandatory),
},
},
Expand Down Expand Up @@ -322,10 +321,9 @@ func TestPoliciesUpdate_Beta(t *testing.T) {
options := PolicyCreateOptions{
Description: String("A sample policy"),
Kind: OPA,
Query: String("terraform.main"),
Query: String("data.example.rule"),
Enforce: []*EnforcementOptions{
{
Path: String(".rego"),
Mode: EnforcementMode(EnforcementMandatory),
},
},
Expand Down
51 changes: 26 additions & 25 deletions run.go
Expand Up @@ -53,31 +53,32 @@ type RunStatus string

// List all available run statuses.
const (
RunApplied RunStatus = "applied"
RunApplying RunStatus = "applying"
RunApplyQueued RunStatus = "apply_queued"
RunCanceled RunStatus = "canceled"
RunConfirmed RunStatus = "confirmed"
RunCostEstimated RunStatus = "cost_estimated"
RunCostEstimating RunStatus = "cost_estimating"
RunDiscarded RunStatus = "discarded"
RunErrored RunStatus = "errored"
RunFetching RunStatus = "fetching"
RunFetchingCompleted RunStatus = "fetching_completed"
RunPending RunStatus = "pending"
RunPlanned RunStatus = "planned"
RunPlannedAndFinished RunStatus = "planned_and_finished"
RunPlanning RunStatus = "planning"
RunPlanQueued RunStatus = "plan_queued"
RunPolicyChecked RunStatus = "policy_checked"
RunPolicyChecking RunStatus = "policy_checking"
RunPolicyOverride RunStatus = "policy_override"
RunPolicySoftFailed RunStatus = "policy_soft_failed"
RunPostPlanCompleted RunStatus = "post_plan_completed"
RunPostPlanRunning RunStatus = "post_plan_running"
RunPrePlanCompleted RunStatus = "pre_plan_completed"
RunPrePlanRunning RunStatus = "pre_plan_running"
RunQueuing RunStatus = "queuing"
RunApplied RunStatus = "applied"
RunApplying RunStatus = "applying"
RunApplyQueued RunStatus = "apply_queued"
RunCanceled RunStatus = "canceled"
RunConfirmed RunStatus = "confirmed"
RunCostEstimated RunStatus = "cost_estimated"
RunCostEstimating RunStatus = "cost_estimating"
RunDiscarded RunStatus = "discarded"
RunErrored RunStatus = "errored"
RunFetching RunStatus = "fetching"
RunFetchingCompleted RunStatus = "fetching_completed"
RunPending RunStatus = "pending"
RunPlanned RunStatus = "planned"
RunPlannedAndFinished RunStatus = "planned_and_finished"
RunPlanning RunStatus = "planning"
RunPlanQueued RunStatus = "plan_queued"
RunPolicyChecked RunStatus = "policy_checked"
RunPolicyChecking RunStatus = "policy_checking"
RunPolicyOverride RunStatus = "policy_override"
RunPolicySoftFailed RunStatus = "policy_soft_failed"
RunPostPlanAwaitingDecision RunStatus = "post_plan_awaiting_decision"
RunPostPlanCompleted RunStatus = "post_plan_completed"
RunPostPlanRunning RunStatus = "post_plan_running"
RunPrePlanCompleted RunStatus = "pre_plan_completed"
RunPrePlanRunning RunStatus = "pre_plan_running"
RunQueuing RunStatus = "queuing"
)

// RunSource represents a source type of a run.
Expand Down
1 change: 1 addition & 0 deletions task_result.go
Expand Up @@ -29,6 +29,7 @@ const (
TaskPending TaskResultStatus = "pending"
TaskRunning TaskResultStatus = "running"
TaskUnreachable TaskResultStatus = "unreachable"
TaskErrored TaskResultStatus = "errored"
)

// TaskEnforcementLevel is an enum that describes the enforcement levels for a run task
Expand Down
65 changes: 64 additions & 1 deletion task_stages.go
Expand Up @@ -15,8 +15,12 @@ type TaskStages interface {
// Read a task stage by ID
Read(ctx context.Context, taskStageID string, options *TaskStageReadOptions) (*TaskStage, error)

// List all task stages for a given rrun
// List all task stages for a given run
List(ctx context.Context, runID string, options *TaskStageListOptions) (*TaskStageList, error)

// **Note: This function is still in BETA and subject to change.**
// Override a task stage for a given run
Override(ctx context.Context, taskStageID string, options TaskStageOverrideOptions) (*TaskStage, error)
}

// taskStages implements TaskStages
Expand All @@ -33,19 +37,51 @@ const (
PreApply Stage = "pre_apply"
)

// TaskStageStatus is an enum that represents all possible statuses for a task stage
type TaskStageStatus string

const (
TaskStagePending TaskStageStatus = "pending"
TaskStageRunning TaskStageStatus = "running"
TaskStagePassed TaskStageStatus = "passed"
TaskStageFailed TaskStageStatus = "failed"
TaskStageAwaitingOverride TaskStageStatus = "awaiting_override"
)

// Permissions represents the permission types for overridding a task stage
type Permissions struct {
CanOverridePolicy *bool `jsonapi:"attr,can-override-policy"`
CanOverrideTasks *bool `jsonapi:"attr,can-override-tasks"`
CanOverride *bool `jsonapi:"attr,can-override"`
}

// Actions represents a task stage actions
type Actions struct {
IsOverridable *bool `jsonapi:"attr,is-overridable"`
}

// TaskStage represents a TFC/E run's stage where run tasks can occur
type TaskStage struct {
ID string `jsonapi:"primary,task-stages"`
Stage Stage `jsonapi:"attr,stage"`
Status TaskStageStatus `jsonapi:"attr,status"`
StatusTimestamps TaskStageStatusTimestamps `jsonapi:"attr,status-timestamps"`
CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"`
UpdatedAt time.Time `jsonapi:"attr,updated-at,iso8601"`
Permissions *Permissions `jsonapi:"attr,permissions"`
Actions *Actions `jsonapi:"attr,actions"`

Run *Run `jsonapi:"relation,run"`
TaskResults []*TaskResult `jsonapi:"relation,task-results"`
PolicyEvaluations []*PolicyEvaluation `jsonapi:"relation,policy-evaluations"`
}

// TaskStageOverrideOptions represents the options for overriding a TaskStage.
type TaskStageOverrideOptions struct {
// An optional explanation for why the stage was overridden
Comment *string `json:"comment,omitempty"`
}

// TaskStageList represents a list of task stages
type TaskStageList struct {
*Pagination
Expand All @@ -66,6 +102,9 @@ type TaskStageIncludeOpt string

const TaskStageTaskResults TaskStageIncludeOpt = "task_results"

// **Note: This field is still in BETA and subject to change.**
const PolicyEvaluationsTaskResults TaskStageIncludeOpt = "policy_evaluations"

// TaskStageReadOptions represents the set of options when reading a task stage
type TaskStageReadOptions struct {
// Optional: A list of relations to include.
Expand Down Expand Up @@ -123,6 +162,28 @@ func (s *taskStages) List(ctx context.Context, runID string, options *TaskStageL
return tlist, nil
}

// **Note: This function is still in BETA and subject to change.**
// Override a task stages for a run
func (s *taskStages) Override(ctx context.Context, taskStageID string, options TaskStageOverrideOptions) (*TaskStage, error) {
if !validStringID(&taskStageID) {
return nil, ErrInvalidTaskStageID
}

u := fmt.Sprintf("task-stages/%s/actions/override", taskStageID)
req, err := s.client.NewRequest("POST", u, &options)
if err != nil {
return nil, err
}

t := &TaskStage{}
err = req.Do(ctx, t)
if err != nil {
return nil, err
}

return t, nil
}

func (o *TaskStageReadOptions) valid() error {
if o == nil {
return nil // nothing to validate
Expand All @@ -140,6 +201,8 @@ func validateTaskStageIncludeParams(params []TaskStageIncludeOpt) error {
switch p {
case TaskStageTaskResults:
// do nothing
case PolicyEvaluationsTaskResults:
// do nothing
default:
return ErrInvalidIncludeValue
}
Expand Down

0 comments on commit 0f28f32

Please sign in to comment.