Skip to content

Commit

Permalink
Merge pull request #1163 from diggerhq/feat/show-terraform-json
Browse files Browse the repository at this point in the history
terraform show for plan storage to convert it to json
  • Loading branch information
ZIJ authored Feb 15, 2024
2 parents 0b9679a + 7961eee commit d6ea360
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 24 deletions.
34 changes: 33 additions & 1 deletion cli/pkg/core/execution/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,38 @@ func (d ProjectPathProvider) StoredPlanFilePath() string {
return path.Join(d.ProjectNamespace, d.PlanFileName())
}

func (d DiggerExecutor) RetrievePlanJson() (string, error) {
executor := d
planStorage := executor.PlanStorage
planPathProvider := executor.PlanPathProvider
storedPlanExists, err := planStorage.PlanExists(planPathProvider.ArtifactName())
if err != nil {
return "", fmt.Errorf("failed to check if stored plan exists. %v", err)
}
if storedPlanExists {
log.Printf("Pre-apply plan retrieval: stored plan exists in artefact, retrieving")
storedPlanPath, err := planStorage.RetrievePlan(planPathProvider.LocalPlanFilePath(), planPathProvider.ArtifactName())
if err != nil {
return "", fmt.Errorf("failed to retrieve stored plan path. %v", err)
}

// Running terraform init to load provider
for _, step := range executor.PlanStage.Steps {
if step.Action == "init" {
executor.TerraformExecutor.Init(step.ExtraArgs, executor.StateEnvVars)
break
}
}

showArgs := []string{"-no-color", "-json", *storedPlanPath}
terraformPlanOutput, _, _ := executor.TerraformExecutor.Show(showArgs, executor.CommandEnvVars)
return terraformPlanOutput, nil

} else {
return "", fmt.Errorf("stored plan does not exist")
}
}

func (d DiggerExecutor) Plan() (*terraform.PlanSummary, bool, bool, string, string, error) {
plan := ""
terraformPlanOutput := ""
Expand Down Expand Up @@ -252,7 +284,7 @@ func (d DiggerExecutor) Apply() (bool, string, error) {
var plansFilename *string
if d.PlanStorage != nil {
var err error
plansFilename, err = d.PlanStorage.RetrievePlan(d.PlanPathProvider.LocalPlanFilePath(), d.PlanPathProvider.StoredPlanFilePath())
plansFilename, err = d.PlanStorage.RetrievePlan(d.PlanPathProvider.LocalPlanFilePath(), d.PlanPathProvider.ArtifactName())
if err != nil {
return false, "", fmt.Errorf("error retrieving plan: %v", err)
}
Expand Down
27 changes: 4 additions & 23 deletions cli/pkg/digger/digger.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ func run(command string, job orchestrator.Job, policyChecker policy.Checker, org
PlanPathProvider: planPathProvider,
},
}
executor := diggerExecutor.Executor.(execution.DiggerExecutor)

switch command {

Expand Down Expand Up @@ -371,13 +372,14 @@ func run(command string, job orchestrator.Job, policyChecker policy.Checker, org
var planPolicyViolations []string

if os.Getenv("PLAN_UPLOAD_DESTINATION") != "" {
storedPlanJson, err := retrievePlanBeforeApply(planStorage, planPathProvider, diggerExecutor.Executor.(execution.DiggerExecutor))
terraformPlanJsonStr, err := executor.RetrievePlanJson()
if err != nil {
msg := fmt.Sprintf("Failed to retrieve stored plan. %v", err)
log.Printf(msg)
return nil, msg, fmt.Errorf(msg)
}
_, violations, err := policyChecker.CheckPlanPolicy(SCMrepository, SCMOrganisation, job.ProjectName, storedPlanJson)

_, violations, err := policyChecker.CheckPlanPolicy(SCMrepository, SCMOrganisation, job.ProjectName, terraformPlanJsonStr)
if err != nil {
msg := fmt.Sprintf("Failed to check plan policy. %v", err)
log.Printf(msg)
Expand Down Expand Up @@ -485,27 +487,6 @@ func run(command string, job orchestrator.Job, policyChecker policy.Checker, org
return &execution.DiggerExecutorResult{}, "", nil
}

func retrievePlanBeforeApply(planStorage storage.PlanStorage, planPathProvider execution.PlanPathProvider, diggerExecutor execution.DiggerExecutor) (string, error) {
storedPlanExists, err := planStorage.PlanExists(diggerExecutor.ProjectName)
if err != nil {
return "", fmt.Errorf("failed to check if stored plan exists. %v", err)
}
if storedPlanExists {
log.Printf("Pre-apply plan retrieval: stored plan exists")
storedPlanPath, err := planStorage.RetrievePlan(planPathProvider.LocalPlanFilePath(), planPathProvider.ArtifactName())
if err != nil {
return "", fmt.Errorf("failed to retrieve stored plan path. %v", err)
}
planBytes, err := os.ReadFile(*storedPlanPath)
if err != nil {
return "", fmt.Errorf("failed to read stored plan file. %v", err)
}
return string(planBytes), nil
} else {
return "", fmt.Errorf("stored plan does not exist")
}
}

func reportApplyMergeabilityError(reporter core_reporting.Reporter) string {
comment := "cannot perform Apply since the PR is not currently mergeable"
log.Println(comment)
Expand Down
1 change: 1 addition & 0 deletions cli/pkg/policy/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ func (p DiggerPolicyChecker) CheckPlanPolicy(SCMrepository string, SCMOrganisati
return false, nil, fmt.Errorf("failed get plan policy: %v", err)
}
var parsedPlanOutput map[string]interface{}

err = json.Unmarshal([]byte(planOutput), &parsedPlanOutput)
if err != nil {
return false, nil, fmt.Errorf("failed to parse json terraform output to map: %v", err)
Expand Down

0 comments on commit d6ea360

Please sign in to comment.