func (runner *TfJobRunner) Status(ctx context.Context, id string) (isDone bool, err error) {
	deployment, err := db_service.GetTerraformDeploymentById(ctx, id)
	if err != nil {
		return true, err
	}
	switch deployment.LastOperationState {
	case Succeeded:
		return true, nil
	case Failed:
		return true, errors.New(deployment.LastOperationMessage)
	default:
		return false, nil
	}
}
Status gets the status of the most recent job on the workspace.
If isDone is true, then the status of the operation will not change again.
if isDone is false, then the operation is ongoing.
package tf
import (
	"context"
	"errors"
	"fmt"
	"time"
	"code.cloudfoundry.org/lager"
	"github.com/GoogleCloudPlatform/gcp-service-broker/db_service/models"
	"github.com/GoogleCloudPlatform/gcp-service-broker/db_service"
	"github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/tf/wrapper"
	"github.com/GoogleCloudPlatform/gcp-service-broker/utils"
)
const (
	InProgress = "in progress"
	Succeeded  = "succeeded"
	Failed     = "failed"
)
func NewTfJobRunerFromEnv() (*TfJobRunner, error) {
	projectId, err := utils.GetDefaultProjectId()
	if err != nil {
		return nil, err
	}
	return NewTfJobRunnerForProject(projectId), nil
}
func NewTfJobRunnerForProject(projectId string) *TfJobRunner {
	return &TfJobRunner{
		ProjectId:      projectId,
		ServiceAccount: utils.GetServiceAccountJson(),
	}
}
type TfJobRunner struct {
	ProjectId      string
	ServiceAccount string
	Executor wrapper.TerraformExecutor
}
func (runner *TfJobRunner) StageJob(ctx context.Context, jobId string, workspace *wrapper.TerraformWorkspace) error {
	workspace.Executor = runner.Executor
	if err := workspace.Validate(); err != nil {
		return err
	}
	workspaceString, err := workspace.Serialize()
	if err != nil {
		return err
	}
	deployment := &models.TerraformDeployment{
		ID:                jobId,
		Workspace:         workspaceString,
		LastOperationType: "validation",
	}
	return runner.operationFinished(nil, workspace, deployment)
}
func (runner *TfJobRunner) markJobStarted(ctx context.Context, deployment *models.TerraformDeployment, operationType string) error {
	deployment.LastOperationType = operationType
	deployment.LastOperationState = InProgress
	deployment.LastOperationMessage = ""
	if err := db_service.SaveTerraformDeployment(ctx, deployment); err != nil {
		return err
	}
	return nil
}
func (runner *TfJobRunner) hydrateWorkspace(ctx context.Context, deployment *models.TerraformDeployment) (*wrapper.TerraformWorkspace, error) {
	ws, err := wrapper.DeserializeWorkspace(deployment.Workspace)
	if err != nil {
		return nil, err
	}
	env := map[string]string{
		"GOOGLE_CREDENTIALS": runner.ServiceAccount,
		"GOOGLE_PROJECT":     runner.ProjectId,
	}
	ws.Executor = wrapper.CustomEnvironmentExecutor(env, runner.Executor)
	logger := utils.NewLogger("job-runner")
	logger.Info("wrapping", lager.Data{
		"wrapper": ws,
	})
	return ws, nil
}
func (runner *TfJobRunner) Create(ctx context.Context, id string) error {
	deployment, err := db_service.GetTerraformDeploymentById(ctx, id)
	if err != nil {
		return err
	}
	workspace, err := runner.hydrateWorkspace(ctx, deployment)
	if err != nil {
		return err
	}
	if err := runner.markJobStarted(ctx, deployment, models.ProvisionOperationType); err != nil {
		return err
	}
	go func() {
		err := workspace.Apply()
		runner.operationFinished(err, workspace, deployment)
	}()
	return nil
}
func (runner *TfJobRunner) Destroy(ctx context.Context, id string) error {
	deployment, err := db_service.GetTerraformDeploymentById(ctx, id)
	if err != nil {
		return err
	}
	workspace, err := runner.hydrateWorkspace(ctx, deployment)
	if err != nil {
		return err
	}
	if err := runner.markJobStarted(ctx, deployment, models.DeprovisionOperationType); err != nil {
		return err
	}
	go func() {
		err := workspace.Destroy()
		runner.operationFinished(err, workspace, deployment)
	}()
	return nil
}
func (runner *TfJobRunner) operationFinished(err error, workspace *wrapper.TerraformWorkspace, deployment *models.TerraformDeployment) error {
	if err == nil {
		deployment.LastOperationState = Succeeded
		deployment.LastOperationMessage = ""
	} else {
		deployment.LastOperationState = Failed
		deployment.LastOperationMessage = err.Error()
	}
	workspaceString, err := workspace.Serialize()
	if err != nil {
		deployment.LastOperationState = Failed
		deployment.LastOperationMessage = fmt.Sprintf("couldn't serialize workspace, contact your operator for cleanup: %s", err.Error())
	}
	deployment.Workspace = workspaceString
	return db_service.SaveTerraformDeployment(context.Background(), deployment)
}