diff --git a/cli/pkg/core/execution/execution.go b/cli/pkg/core/execution/execution.go index 770a3121f..aebc1496e 100644 --- a/cli/pkg/core/execution/execution.go +++ b/cli/pkg/core/execution/execution.go @@ -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 := "" @@ -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) } diff --git a/cli/pkg/digger/digger.go b/cli/pkg/digger/digger.go index d05dc1c37..7124d4289 100644 --- a/cli/pkg/digger/digger.go +++ b/cli/pkg/digger/digger.go @@ -259,6 +259,7 @@ func run(command string, job orchestrator.Job, policyChecker policy.Checker, org PlanPathProvider: planPathProvider, }, } + executor := diggerExecutor.Executor.(execution.DiggerExecutor) switch command { @@ -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) @@ -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) diff --git a/cli/pkg/policy/policy.go b/cli/pkg/policy/policy.go index 9fd68c3cb..b780fb04b 100644 --- a/cli/pkg/policy/policy.go +++ b/cli/pkg/policy/policy.go @@ -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)