command: Get command, not functional yet. Converted to use modules.
This commit is contained in:
parent
bea81d7710
commit
ed538a9594
|
@ -68,7 +68,10 @@ func (c *ApplyCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Build the context based on the arguments given
|
||||
ctx, planned, err := c.Context(configPath, statePath)
|
||||
ctx, planned, err := c.Context(contextOpts{
|
||||
Path: configPath,
|
||||
StatePath: statePath,
|
||||
})
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
return 1
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetCommand is a Command implementation that takes a Terraform
|
||||
// configuration and downloads all the modules.
|
||||
type GetCommand struct {
|
||||
Meta
|
||||
}
|
||||
|
||||
func (c *GetCommand) Run(args []string) int {
|
||||
args = c.Meta.process(args, false)
|
||||
|
||||
cmdFlags := flag.NewFlagSet("get", flag.ContinueOnError)
|
||||
cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
var path string
|
||||
args = cmdFlags.Args()
|
||||
if len(args) > 1 {
|
||||
c.Ui.Error("The graph command expects one argument.\n")
|
||||
cmdFlags.Usage()
|
||||
return 1
|
||||
} else if len(args) == 1 {
|
||||
path = args[0]
|
||||
} else {
|
||||
var err error
|
||||
path, err = os.Getwd()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error getting pwd: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
_, _, err := c.Context(contextOpts{
|
||||
Path: path,
|
||||
})
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error loading Terraform: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *GetCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: terraform get [options] PATH
|
||||
|
||||
Downloads and installs modules needed for the configuration given by
|
||||
PATH.
|
||||
|
||||
This recursively downloads all modules needed, such as modules
|
||||
imported by modules imported by the root and so on. If a module is
|
||||
already downloaded, it will not be redownloaded or checked for updates
|
||||
unless the -update flag is specified.
|
||||
|
||||
Options:
|
||||
|
||||
-update=false If true, modules already downloaded will be checked
|
||||
for updates and updated if necessary.
|
||||
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *GetCommand) Synopsis() string {
|
||||
return "Download and install modules for the configuration"
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
ui := new(cli.MockUi)
|
||||
c := &GetCommand{
|
||||
Meta: Meta{
|
||||
ContextOpts: testCtxConfig(testProvider()),
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
testFixturePath("graph"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestGet_multipleArgs(t *testing.T) {
|
||||
ui := new(cli.MockUi)
|
||||
c := &GetCommand{
|
||||
Meta: Meta{
|
||||
ContextOpts: testCtxConfig(testProvider()),
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"bad",
|
||||
"bad",
|
||||
}
|
||||
if code := c.Run(args); code != 1 {
|
||||
t.Fatalf("bad: \n%s", ui.OutputWriter.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestGet_noArgs(t *testing.T) {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if err := os.Chdir(testFixturePath("graph")); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.Chdir(cwd)
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &GraphCommand{
|
||||
Meta: Meta{
|
||||
ContextOpts: testCtxConfig(testProvider()),
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
|
||||
args := []string{}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
||||
}
|
||||
}
|
|
@ -40,7 +40,10 @@ func (c *GraphCommand) Run(args []string) int {
|
|||
}
|
||||
}
|
||||
|
||||
ctx, _, err := c.Context(path, "")
|
||||
ctx, _, err := c.Context(contextOpts{
|
||||
Path: path,
|
||||
StatePath: "",
|
||||
})
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error loading Terraform: %s", err))
|
||||
return 1
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/hashicorp/terraform/config"
|
||||
"github.com/hashicorp/terraform/config/module"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/mitchellh/colorstring"
|
||||
|
@ -46,11 +46,11 @@ func (m *Meta) Colorize() *colorstring.Colorize {
|
|||
|
||||
// Context returns a Terraform Context taking into account the context
|
||||
// options used to initialize this meta configuration.
|
||||
func (m *Meta) Context(path, statePath string) (*terraform.Context, bool, error) {
|
||||
func (m *Meta) Context(copts contextOpts) (*terraform.Context, bool, error) {
|
||||
opts := m.contextOpts()
|
||||
|
||||
// First try to just read the plan directly from the path given.
|
||||
f, err := os.Open(path)
|
||||
f, err := os.Open(copts.Path)
|
||||
if err == nil {
|
||||
plan, err := terraform.ReadPlan(f)
|
||||
f.Close()
|
||||
|
@ -69,8 +69,8 @@ func (m *Meta) Context(path, statePath string) (*terraform.Context, bool, error)
|
|||
|
||||
// Load up the state
|
||||
var state *terraform.State
|
||||
if statePath != "" {
|
||||
f, err := os.Open(statePath)
|
||||
if copts.StatePath != "" {
|
||||
f, err := os.Open(copts.StatePath)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
// If the state file doesn't exist, it is okay, since it
|
||||
// is probably a new infrastructure.
|
||||
|
@ -88,15 +88,13 @@ func (m *Meta) Context(path, statePath string) (*terraform.Context, bool, error)
|
|||
// Store the loaded state
|
||||
m.state = state
|
||||
|
||||
config, err := config.LoadDir(path)
|
||||
// Load the root module
|
||||
mod, err := module.NewTreeModule("", copts.Path)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("Error loading config: %s", err)
|
||||
}
|
||||
if err := config.Validate(); err != nil {
|
||||
return nil, false, fmt.Errorf("Error validating config: %s", err)
|
||||
}
|
||||
|
||||
opts.Config = config
|
||||
opts.Config = mod.Config()
|
||||
opts.State = state
|
||||
ctx := terraform.NewContext(opts)
|
||||
return ctx, false, nil
|
||||
|
@ -207,3 +205,18 @@ func (m *Meta) uiHook() *UiHook {
|
|||
Ui: m.Ui,
|
||||
}
|
||||
}
|
||||
|
||||
// contextOpts are the options used to load a context from a command.
|
||||
type contextOpts struct {
|
||||
// Path to the directory where the root module is.
|
||||
Path string
|
||||
|
||||
// StatePath is the path to the state file. If this is empty, then
|
||||
// no state will be loaded. It is also okay for this to be a path to
|
||||
// a file that doesn't exist; it is assumed that this means that there
|
||||
// is simply no state.
|
||||
StatePath string
|
||||
|
||||
// GetMode is the module.GetMode to use when loading the module tree.
|
||||
GetMode module.GetMode
|
||||
}
|
||||
|
|
|
@ -65,7 +65,10 @@ func (c *PlanCommand) Run(args []string) int {
|
|||
backupPath = statePath + DefaultBackupExtention
|
||||
}
|
||||
|
||||
ctx, _, err := c.Context(path, statePath)
|
||||
ctx, _, err := c.Context(contextOpts{
|
||||
Path: path,
|
||||
StatePath: statePath,
|
||||
})
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
return 1
|
||||
|
|
|
@ -84,7 +84,10 @@ func (c *RefreshCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Build the context based on the arguments given
|
||||
ctx, _, err := c.Context(configPath, statePath)
|
||||
ctx, _, err := c.Context(contextOpts{
|
||||
Path: configPath,
|
||||
StatePath: statePath,
|
||||
})
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
return 1
|
||||
|
|
|
@ -40,6 +40,12 @@ func init() {
|
|||
}, nil
|
||||
},
|
||||
|
||||
"get": func() (cli.Command, error) {
|
||||
return &command.GetCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
|
||||
"graph": func() (cli.Command, error) {
|
||||
return &command.GraphCommand{
|
||||
Meta: meta,
|
||||
|
|
|
@ -58,6 +58,11 @@ func NewTreeModule(name, dir string) (*Tree, error) {
|
|||
return NewTree(name, c), nil
|
||||
}
|
||||
|
||||
// Config returns the configuration for this module.
|
||||
func (t *Tree) Config() *config.Config {
|
||||
return t.config
|
||||
}
|
||||
|
||||
// Children returns the children of this tree (the modules that are
|
||||
// imported by this root).
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue