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
|
// 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 {
|
if err != nil {
|
||||||
c.Ui.Error(err.Error())
|
c.Ui.Error(err.Error())
|
||||||
return 1
|
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 {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Error loading Terraform: %s", err))
|
c.Ui.Error(fmt.Sprintf("Error loading Terraform: %s", err))
|
||||||
return 1
|
return 1
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/config"
|
"github.com/hashicorp/terraform/config/module"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
"github.com/mitchellh/colorstring"
|
"github.com/mitchellh/colorstring"
|
||||||
|
@ -46,11 +46,11 @@ func (m *Meta) Colorize() *colorstring.Colorize {
|
||||||
|
|
||||||
// Context returns a Terraform Context taking into account the context
|
// Context returns a Terraform Context taking into account the context
|
||||||
// options used to initialize this meta configuration.
|
// 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()
|
opts := m.contextOpts()
|
||||||
|
|
||||||
// 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(copts.Path)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
plan, err := terraform.ReadPlan(f)
|
plan, err := terraform.ReadPlan(f)
|
||||||
f.Close()
|
f.Close()
|
||||||
|
@ -69,8 +69,8 @@ func (m *Meta) Context(path, statePath string) (*terraform.Context, bool, error)
|
||||||
|
|
||||||
// Load up the state
|
// Load up the state
|
||||||
var state *terraform.State
|
var state *terraform.State
|
||||||
if statePath != "" {
|
if copts.StatePath != "" {
|
||||||
f, err := os.Open(statePath)
|
f, err := os.Open(copts.StatePath)
|
||||||
if err != nil && os.IsNotExist(err) {
|
if err != nil && os.IsNotExist(err) {
|
||||||
// If the state file doesn't exist, it is okay, since it
|
// If the state file doesn't exist, it is okay, since it
|
||||||
// is probably a new infrastructure.
|
// is probably a new infrastructure.
|
||||||
|
@ -88,15 +88,13 @@ func (m *Meta) Context(path, statePath string) (*terraform.Context, bool, error)
|
||||||
// Store the loaded state
|
// Store the loaded state
|
||||||
m.state = state
|
m.state = state
|
||||||
|
|
||||||
config, err := config.LoadDir(path)
|
// Load the root module
|
||||||
|
mod, err := module.NewTreeModule("", copts.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, fmt.Errorf("Error loading config: %s", err)
|
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
|
opts.State = state
|
||||||
ctx := terraform.NewContext(opts)
|
ctx := terraform.NewContext(opts)
|
||||||
return ctx, false, nil
|
return ctx, false, nil
|
||||||
|
@ -207,3 +205,18 @@ func (m *Meta) uiHook() *UiHook {
|
||||||
Ui: m.Ui,
|
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
|
backupPath = statePath + DefaultBackupExtention
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, _, err := c.Context(path, statePath)
|
ctx, _, err := c.Context(contextOpts{
|
||||||
|
Path: path,
|
||||||
|
StatePath: statePath,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(err.Error())
|
c.Ui.Error(err.Error())
|
||||||
return 1
|
return 1
|
||||||
|
|
|
@ -84,7 +84,10 @@ func (c *RefreshCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the context based on the arguments given
|
// 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 {
|
if err != nil {
|
||||||
c.Ui.Error(err.Error())
|
c.Ui.Error(err.Error())
|
||||||
return 1
|
return 1
|
||||||
|
|
|
@ -40,6 +40,12 @@ func init() {
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"get": func() (cli.Command, error) {
|
||||||
|
return &command.GetCommand{
|
||||||
|
Meta: meta,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
|
||||||
"graph": func() (cli.Command, error) {
|
"graph": func() (cli.Command, error) {
|
||||||
return &command.GraphCommand{
|
return &command.GraphCommand{
|
||||||
Meta: meta,
|
Meta: meta,
|
||||||
|
|
|
@ -58,6 +58,11 @@ func NewTreeModule(name, dir string) (*Tree, error) {
|
||||||
return NewTree(name, c), nil
|
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
|
// Children returns the children of this tree (the modules that are
|
||||||
// imported by this root).
|
// imported by this root).
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue