dartboard/test/examples/tfexec/tfexec_test.go

141 lines
4.1 KiB
Go

package examples
import (
"context"
"encoding/json"
"os"
"testing"
"time"
"github.com/hashicorp/terraform-exec/tfexec"
"github.com/rancher/shepherd/pkg/config"
namegen "github.com/rancher/shepherd/pkg/namegenerator"
"github.com/rancher/shepherd/pkg/session"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)
type TfApplyDestroy struct {
suite.Suite
session *session.Session
client *tfexec.Terraform
config *Config
}
func (s *TfApplyDestroy) TearDownTest() {
log.Info("TEARING DOWN")
s.TfDestroy()
_, err := os.Stat(s.config.PlanFilePath)
if err == nil {
err := os.Remove(s.config.PlanFilePath)
require.NoError(s.T(), err)
}
}
func (s *TfApplyDestroy) SetupSuite() {
testSession := session.NewSession()
s.session = testSession
s.config = new(Config)
config.LoadConfig(ConfigurationFileKey, s.config)
client, err := tfexec.NewTerraform(s.config.WorkingDir, s.config.ExecPath)
require.NoError(s.T(), err)
log.Info("Successfully created tfexec instance")
err = client.Init(context.Background())
require.NoError(s.T(), err)
s.client = client
log.Info("Successfully ran `terraform init` on module at: ", s.client.WorkingDir())
s.TfSetupWorkspace()
}
func (s *TfApplyDestroy) TfPlanJSON() {
if s.config.PlanFilePath == "" {
s.config.PlanFilePath = s.config.PlanOpts.OutDir + "/tfexec_plan_" + time.Now().Format(time.RFC3339) + ".tfplan"
}
outOpt := tfexec.PlanOption(tfexec.Out(s.config.PlanFilePath))
varFileOpt := tfexec.PlanOption(tfexec.VarFile(s.config.VarFilePath))
_, err := s.client.PlanJSON(context.Background(), nil, varFileOpt, outOpt)
require.NoError(s.T(), err)
log.Info("Successfully ran `terraform plan -json -var-file=" + s.config.VarFilePath + " -out=" + s.config.PlanFilePath + "`")
}
func (s *TfApplyDestroy) TfApplyPlanJSON() {
planFileOpt := tfexec.ApplyOption(tfexec.DirOrPlan(s.config.PlanFilePath))
err := s.client.ApplyJSON(context.Background(), os.Stdout, planFileOpt)
require.NoError(s.T(), err)
log.Info("Successfully ran `terraform apply -json " + s.config.PlanFilePath)
// state, err := s.client.Show(context.Background())
// require.NoError(s.T(), err)
// out, err := json.Marshal(state.Values.RootModule.Resources)
// require.NoError(s.T(), err)
// log.Info("TF State: " + string(out))
}
func (s *TfApplyDestroy) TfOutput() {
outputs, err := s.client.Output(context.Background())
require.NoError(s.T(), err)
outputsJSON, err := json.Marshal(outputs)
require.NoError(s.T(), err)
log.Info("Output: " + string(outputsJSON))
}
func (s *TfApplyDestroy) TfWorkspaceExists(ctx context.Context, workspace string) bool {
wsList, _, err := s.client.WorkspaceList(context.Background())
require.NoError(s.T(), err)
for _, str := range wsList {
if str == workspace {
return true
}
}
return false
}
func (s *TfApplyDestroy) TfSetupWorkspace() {
var err error
if s.config.WorkspaceName != "" {
if s.TfWorkspaceExists(context.Background(), s.config.WorkspaceName) {
err = s.client.WorkspaceSelect(context.Background(), s.config.WorkspaceName)
} else {
err = s.client.WorkspaceNew(context.Background(), s.config.WorkspaceName)
}
} else {
s.config.WorkspaceName = "dartboard-tfexec_test-" + namegen.RandStringLower(5)
err = s.client.WorkspaceNew(context.Background(), s.config.WorkspaceName)
}
require.NoError(s.T(), err)
log.Info("Successfully setup workspace: " + s.config.WorkspaceName)
}
func (s *TfApplyDestroy) TfDestroy() {
varFileOpt := tfexec.DestroyOption(tfexec.VarFile(s.config.VarFilePath))
err := s.client.DestroyJSON(context.Background(), os.Stdout, varFileOpt)
require.NoError(s.T(), err)
log.Info("Successfully ran `terraform destroy -json -var-file=" + s.config.VarFilePath + "`")
}
func (s *TfApplyDestroy) TestTfPlanJSON() {
s.TfPlanJSON()
}
func (s *TfApplyDestroy) TestTfApplyPlanJSON() {
s.Run("Apply plan with planfile", func() {
s.TfPlanJSON()
s.TfApplyPlanJSON()
})
}
func (s *TfApplyDestroy) TestTfOutput() {
_, err := os.Stat(s.config.PlanFilePath)
if err != nil {
s.TfPlanJSON()
}
s.TfOutput()
}
func TestTfApplyDestroy(t *testing.T) {
suite.Run(t, new(TfApplyDestroy))
}