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