command: use new API
This commit is contained in:
parent
adcd6486a2
commit
a6ae7230d1
|
@ -13,9 +13,9 @@ import (
|
|||
// ApplyCommand is a Command implementation that applies a Terraform
|
||||
// configuration and actually builds or changes infrastructure.
|
||||
type ApplyCommand struct {
|
||||
ShutdownCh <-chan struct{}
|
||||
TFConfig *terraform.Config
|
||||
Ui cli.Ui
|
||||
ShutdownCh <-chan struct{}
|
||||
ContextOpts *terraform.ContextOpts
|
||||
Ui cli.Ui
|
||||
}
|
||||
|
||||
func (c *ApplyCommand) Run(args []string) int {
|
||||
|
@ -44,21 +44,14 @@ func (c *ApplyCommand) Run(args []string) int {
|
|||
stateOutPath = statePath
|
||||
}
|
||||
|
||||
// Initialize Terraform right away
|
||||
c.TFConfig.Hooks = append(c.TFConfig.Hooks, &UiHook{Ui: c.Ui})
|
||||
tf, err := terraform.New(c.TFConfig)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error initializing Terraform: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
// Attempt to read a plan from the path given. This is how we test that
|
||||
// it is a plan or not (kind of jank, but if it quacks like a duck...)
|
||||
planStatePath := statePath
|
||||
if init {
|
||||
planStatePath = ""
|
||||
}
|
||||
plan, err := PlanArg(configPath, planStatePath, tf)
|
||||
|
||||
// Initialize Terraform right away
|
||||
c.ContextOpts.Hooks = append(c.ContextOpts.Hooks, &UiHook{Ui: c.Ui})
|
||||
ctx, err := ContextArg(configPath, planStatePath, c.ContextOpts)
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
return 1
|
||||
|
@ -67,7 +60,7 @@ func (c *ApplyCommand) Run(args []string) int {
|
|||
errCh := make(chan error)
|
||||
stateCh := make(chan *terraform.State)
|
||||
go func() {
|
||||
state, err := tf.Apply(plan)
|
||||
state, err := ctx.Apply()
|
||||
if err != nil {
|
||||
errCh <- err
|
||||
return
|
||||
|
@ -83,7 +76,7 @@ func (c *ApplyCommand) Run(args []string) int {
|
|||
c.Ui.Output("Interrupt received. Gracefully shutting down...")
|
||||
|
||||
// Stop execution
|
||||
tf.Stop()
|
||||
ctx.Stop()
|
||||
|
||||
// Still get the result, since there is still one
|
||||
select {
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/config"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
@ -16,8 +17,8 @@ func TestApply(t *testing.T) {
|
|||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &ApplyCommand{
|
||||
TFConfig: testTFConfig(p),
|
||||
Ui: ui,
|
||||
ContextOpts: testCtxConfig(p),
|
||||
Ui: ui,
|
||||
}
|
||||
|
||||
args := []string{
|
||||
|
@ -52,8 +53,8 @@ func TestApply_configInvalid(t *testing.T) {
|
|||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &ApplyCommand{
|
||||
TFConfig: testTFConfig(p),
|
||||
Ui: ui,
|
||||
ContextOpts: testCtxConfig(p),
|
||||
Ui: ui,
|
||||
}
|
||||
|
||||
args := []string{
|
||||
|
@ -67,14 +68,16 @@ func TestApply_configInvalid(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestApply_plan(t *testing.T) {
|
||||
planPath := testPlanFile(t, new(terraform.Plan))
|
||||
planPath := testPlanFile(t, &terraform.Plan{
|
||||
Config: new(config.Config),
|
||||
})
|
||||
statePath := testTempFile(t)
|
||||
|
||||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &ApplyCommand{
|
||||
TFConfig: testTFConfig(p),
|
||||
Ui: ui,
|
||||
ContextOpts: testCtxConfig(p),
|
||||
Ui: ui,
|
||||
}
|
||||
|
||||
args := []string{
|
||||
|
@ -115,9 +118,9 @@ func TestApply_shutdown(t *testing.T) {
|
|||
shutdownCh := make(chan struct{})
|
||||
ui := new(cli.MockUi)
|
||||
c := &ApplyCommand{
|
||||
ShutdownCh: shutdownCh,
|
||||
TFConfig: testTFConfig(p),
|
||||
Ui: ui,
|
||||
ContextOpts: testCtxConfig(p),
|
||||
ShutdownCh: shutdownCh,
|
||||
Ui: ui,
|
||||
}
|
||||
|
||||
p.DiffFn = func(
|
||||
|
@ -215,8 +218,8 @@ func TestApply_state(t *testing.T) {
|
|||
|
||||
ui := new(cli.MockUi)
|
||||
c := &ApplyCommand{
|
||||
TFConfig: testTFConfig(p),
|
||||
Ui: ui,
|
||||
ContextOpts: testCtxConfig(p),
|
||||
Ui: ui,
|
||||
}
|
||||
|
||||
// Run the apply command pointing to our existing state
|
||||
|
@ -262,8 +265,8 @@ func TestApply_stateNoExist(t *testing.T) {
|
|||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &ApplyCommand{
|
||||
TFConfig: testTFConfig(p),
|
||||
Ui: ui,
|
||||
ContextOpts: testCtxConfig(p),
|
||||
Ui: ui,
|
||||
}
|
||||
|
||||
args := []string{
|
||||
|
|
|
@ -8,17 +8,17 @@ import (
|
|||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func PlanArg(
|
||||
func ContextArg(
|
||||
path string,
|
||||
statePath string,
|
||||
tf *terraform.Terraform) (*terraform.Plan, error) {
|
||||
opts *terraform.ContextOpts) (*terraform.Context, error) {
|
||||
// First try to just read the plan directly from the path given.
|
||||
f, err := os.Open(path)
|
||||
if err == nil {
|
||||
plan, err := terraform.ReadPlan(f)
|
||||
f.Close()
|
||||
if err == nil {
|
||||
return plan, nil
|
||||
return plan.Context(opts), nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,13 +59,13 @@ func PlanArg(
|
|||
return nil, fmt.Errorf("Error validating config: %s", err)
|
||||
}
|
||||
|
||||
plan, err := tf.Plan(&terraform.PlanOpts{
|
||||
Config: config,
|
||||
State: state,
|
||||
})
|
||||
if err != nil {
|
||||
opts.Config = config
|
||||
opts.State = state
|
||||
ctx := terraform.NewContext(opts)
|
||||
|
||||
if _, err := ctx.Plan(nil); err != nil {
|
||||
return nil, fmt.Errorf("Error running plan: %s", err)
|
||||
}
|
||||
|
||||
return plan, nil
|
||||
return ctx, nil
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@ func testFixturePath(name string) string {
|
|||
return filepath.Join(fixtureDir, name, "main.tf")
|
||||
}
|
||||
|
||||
func testTFConfig(p terraform.ResourceProvider) *terraform.Config {
|
||||
return &terraform.Config{
|
||||
func testCtxConfig(p terraform.ResourceProvider) *terraform.ContextOpts {
|
||||
return &terraform.ContextOpts{
|
||||
Providers: map[string]terraform.ResourceProviderFactory{
|
||||
"test": func() (terraform.ResourceProvider, error) {
|
||||
return p, nil
|
||||
|
|
|
@ -15,8 +15,8 @@ import (
|
|||
// GraphCommand is a Command implementation that takes a Terraform
|
||||
// configuration and outputs the dependency tree in graphical form.
|
||||
type GraphCommand struct {
|
||||
TFConfig *terraform.Config
|
||||
Ui cli.Ui
|
||||
ContextOpts *terraform.ContextOpts
|
||||
Ui cli.Ui
|
||||
}
|
||||
|
||||
func (c *GraphCommand) Run(args []string) int {
|
||||
|
@ -41,7 +41,7 @@ func (c *GraphCommand) Run(args []string) int {
|
|||
|
||||
g, err := terraform.Graph(&terraform.GraphOpts{
|
||||
Config: conf,
|
||||
Providers: c.TFConfig.Providers,
|
||||
Providers: c.ContextOpts.Providers,
|
||||
})
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error creating graph: %s", err))
|
||||
|
|
|
@ -15,8 +15,8 @@ import (
|
|||
// PlanCommand is a Command implementation that compares a Terraform
|
||||
// configuration to an actual infrastructure and shows the differences.
|
||||
type PlanCommand struct {
|
||||
TFConfig *terraform.Config
|
||||
Ui cli.Ui
|
||||
ContextOpts *terraform.ContextOpts
|
||||
Ui cli.Ui
|
||||
}
|
||||
|
||||
func (c *PlanCommand) Run(args []string) int {
|
||||
|
@ -65,26 +65,19 @@ func (c *PlanCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
c.TFConfig.Hooks = append(c.TFConfig.Hooks, &UiHook{Ui: c.Ui})
|
||||
tf, err := terraform.New(c.TFConfig)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error initializing Terraform: %s", err))
|
||||
return 1
|
||||
}
|
||||
c.ContextOpts.Config = b
|
||||
c.ContextOpts.Hooks = append(c.ContextOpts.Hooks, &UiHook{Ui: c.Ui})
|
||||
c.ContextOpts.State = state
|
||||
ctx := terraform.NewContext(c.ContextOpts)
|
||||
|
||||
if refresh {
|
||||
state, err = tf.Refresh(b, state)
|
||||
if err != nil {
|
||||
if _, err := ctx.Refresh(); err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error refreshing state: %s", err))
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
plan, err := tf.Plan(&terraform.PlanOpts{
|
||||
Config: b,
|
||||
Destroy: destroy,
|
||||
State: state,
|
||||
})
|
||||
plan, err := ctx.Plan(&terraform.PlanOpts{Destroy: destroy})
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error running plan: %s", err))
|
||||
return 1
|
||||
|
|
|
@ -26,8 +26,8 @@ func TestPlan_destroy(t *testing.T) {
|
|||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &PlanCommand{
|
||||
TFConfig: testTFConfig(p),
|
||||
Ui: ui,
|
||||
ContextOpts: testCtxConfig(p),
|
||||
Ui: ui,
|
||||
}
|
||||
|
||||
args := []string{
|
||||
|
@ -51,8 +51,8 @@ func TestPlan_noState(t *testing.T) {
|
|||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &PlanCommand{
|
||||
TFConfig: testTFConfig(p),
|
||||
Ui: ui,
|
||||
ContextOpts: testCtxConfig(p),
|
||||
Ui: ui,
|
||||
}
|
||||
|
||||
args := []string{
|
||||
|
@ -87,8 +87,8 @@ func TestPlan_outPath(t *testing.T) {
|
|||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &PlanCommand{
|
||||
TFConfig: testTFConfig(p),
|
||||
Ui: ui,
|
||||
ContextOpts: testCtxConfig(p),
|
||||
Ui: ui,
|
||||
}
|
||||
|
||||
p.DiffReturn = &terraform.ResourceDiff{
|
||||
|
@ -118,8 +118,8 @@ func TestPlan_refresh(t *testing.T) {
|
|||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &PlanCommand{
|
||||
TFConfig: testTFConfig(p),
|
||||
Ui: ui,
|
||||
ContextOpts: testCtxConfig(p),
|
||||
Ui: ui,
|
||||
}
|
||||
|
||||
args := []string{
|
||||
|
@ -162,8 +162,8 @@ func TestPlan_state(t *testing.T) {
|
|||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &PlanCommand{
|
||||
TFConfig: testTFConfig(p),
|
||||
Ui: ui,
|
||||
ContextOpts: testCtxConfig(p),
|
||||
Ui: ui,
|
||||
}
|
||||
|
||||
args := []string{
|
||||
|
|
|
@ -15,8 +15,8 @@ import (
|
|||
// RefreshCommand is a cli.Command implementation that refreshes the state
|
||||
// file.
|
||||
type RefreshCommand struct {
|
||||
TFConfig *terraform.Config
|
||||
Ui cli.Ui
|
||||
ContextOpts *terraform.ContextOpts
|
||||
Ui cli.Ui
|
||||
}
|
||||
|
||||
func (c *RefreshCommand) Run(args []string) int {
|
||||
|
@ -66,14 +66,11 @@ func (c *RefreshCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
c.TFConfig.Hooks = append(c.TFConfig.Hooks, &UiHook{Ui: c.Ui})
|
||||
tf, err := terraform.New(c.TFConfig)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error initializing Terraform: %s", err))
|
||||
return 1
|
||||
}
|
||||
c.ContextOpts.Config = b
|
||||
c.ContextOpts.Hooks = append(c.ContextOpts.Hooks, &UiHook{Ui: c.Ui})
|
||||
ctx := terraform.NewContext(c.ContextOpts)
|
||||
|
||||
state, err = tf.Refresh(b, state)
|
||||
state, err = ctx.Refresh()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error refreshing state: %s", err))
|
||||
return 1
|
||||
|
|
|
@ -30,8 +30,8 @@ func TestRefresh(t *testing.T) {
|
|||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &RefreshCommand{
|
||||
TFConfig: testTFConfig(p),
|
||||
Ui: ui,
|
||||
ContextOpts: testCtxConfig(p),
|
||||
Ui: ui,
|
||||
}
|
||||
|
||||
p.RefreshFn = nil
|
||||
|
@ -96,8 +96,8 @@ func TestRefresh_outPath(t *testing.T) {
|
|||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &RefreshCommand{
|
||||
TFConfig: testTFConfig(p),
|
||||
Ui: ui,
|
||||
ContextOpts: testCtxConfig(p),
|
||||
Ui: ui,
|
||||
}
|
||||
|
||||
p.RefreshFn = nil
|
||||
|
|
|
@ -11,12 +11,6 @@ import (
|
|||
"github.com/mitchellh/osext"
|
||||
)
|
||||
|
||||
// TFConfig is the global base configuration that has the
|
||||
// basic providers registered. Users of this configuration
|
||||
// should copy it (call the Copy method) before using it so
|
||||
// that it isn't corrupted.
|
||||
var TFConfig terraform.Config
|
||||
|
||||
// Config is the structure of the configuration for the Terraform CLI.
|
||||
//
|
||||
// This is not the configuration for Terraform itself. That is in the
|
||||
|
|
|
@ -66,7 +66,7 @@ func NewContext(opts *ContextOpts) *Context {
|
|||
providers: opts.Providers,
|
||||
variables: opts.Variables,
|
||||
|
||||
sh: sh,
|
||||
sh: sh,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue