From 8c6e4e564fb19b3acf65f71bc3cf0619ad9112e8 Mon Sep 17 00:00:00 2001 From: Armon Dadgar Date: Thu, 9 Oct 2014 16:28:05 -0700 Subject: [PATCH] remote: Remove ValidateConfig --- remote/remote.go | 80 ++++++++++++++++++++----------------------- remote/remote_test.go | 42 +++-------------------- 2 files changed, 41 insertions(+), 81 deletions(-) diff --git a/remote/remote.go b/remote/remote.go index 7b18712bc..ba10146ca 100644 --- a/remote/remote.go +++ b/remote/remote.go @@ -152,6 +152,7 @@ func EnsureDirectory() error { // HiddenStatePath is used to return the path to the hidden state file, // should there be one. +// TODO: Rename to LocalStatePath func HiddenStatePath() (string, error) { cwd, err := os.Getwd() if err != nil { @@ -161,8 +162,29 @@ func HiddenStatePath() (string, error) { return path, nil } -// validConfig does a purely logical validation of the remote config -func validConfig(conf *terraform.RemoteState) error { +// HaveLocalState is used to check if we have a local state file +func HaveLocalState() (bool, error) { + path, err := HiddenStatePath() + if err != nil { + return false, err + } + return ExistsFile(path) +} + +// ExistsFile is used to check if a given file exists +func ExistsFile(path string) (bool, error) { + _, err := os.Stat(path) + if err == nil { + return true, nil + } + if os.IsNotExist(err) { + return false, nil + } + return false, err +} + +// ValidConfig does a purely logical validation of the remote config +func ValidConfig(conf *terraform.RemoteState) error { // Verify the remote server configuration is sane if (conf.Server != "" || conf.AuthToken != "") && conf.Name == "" { return fmt.Errorf("Name must be provided for remote state storage") @@ -202,47 +224,6 @@ func ReadLocalState() (*terraform.State, []byte, error) { return state, raw, nil } -// ValidateConfig is used to take a remote state configuration, -// ensure the local directory exists and that the remote state -// does not conflict with an existing state file. -func ValidateConfig(conf *terraform.RemoteState) error { - // Logical validation first - if err := validConfig(conf); err != nil { - return err - } - - // Ensure the hidden directory - if err := EnsureDirectory(); err != nil { - return fmt.Errorf( - "Remote state setup failed: %s", err) - } - - // Check for local state - local, _, err := ReadLocalState() - if err != nil { - return err - } - - // Nothing to check if no local state yet - if local == nil { - return nil - } - - // If the hidden state file has no remote info, something - // is definitely wrong... - if local.Remote == nil { - return fmt.Errorf(`Local state file missing remote storage information. -This is likely a bug, please report it.`) - } - - // Check if there is a conflict - if !local.Remote.Equals(conf) { - return fmt.Errorf( - "Conflicting definitions for remote storage in existing state file") - } - return nil -} - // RefreshState is used to read the remote state given // the configuration for the remote endpoint, and update // the local state if necessary. @@ -376,6 +357,19 @@ func blankState(conf *terraform.RemoteState) ([]byte, error) { return buf.Bytes(), err } +// PersistState is used to persist out the given terraform state +// in our local state cache location. +func PersistState(s *terraform.State) error { + buf := bytes.NewBuffer(nil) + if err := terraform.WriteState(s, buf); err != nil { + return fmt.Errorf("Failed to encode state: %v", err) + } + if err := Persist(buf); err != nil { + return err + } + return nil +} + // Persist is used to write out the state given by a reader (likely // being streamed from a remote server) to the local storage. func Persist(r io.Reader) error { diff --git a/remote/remote_test.go b/remote/remote_test.go index 016ea1ce6..01177b203 100644 --- a/remote/remote_test.go +++ b/remote/remote_test.go @@ -46,22 +46,22 @@ func TestHiddenStatePath(t *testing.T) { func TestValidConfig(t *testing.T) { conf := &terraform.RemoteState{} - if err := validConfig(conf); err != nil { + if err := ValidConfig(conf); err != nil { t.Fatalf("blank should be valid: %v", err) } conf.Server = "http://foo.com" - if err := validConfig(conf); err == nil { + if err := ValidConfig(conf); err == nil { t.Fatalf("server without name") } conf.Server = "" conf.AuthToken = "foo" - if err := validConfig(conf); err == nil { + if err := ValidConfig(conf); err == nil { t.Fatalf("auth without name") } conf.Name = "test" conf.Server = "" conf.AuthToken = "" - if err := validConfig(conf); err != nil { + if err := ValidConfig(conf); err != nil { t.Fatalf("should be valid") } if conf.Server != DefaultServer { @@ -69,40 +69,6 @@ func TestValidConfig(t *testing.T) { } } -func TestValidateConfig(t *testing.T) { - defer testFixCwd(testDir(t)) - remote, srv := testRemote(t, nil) - defer srv.Close() - - // No local state, should validate - if err := ValidateConfig(remote); err != nil { - t.Fatalf("err: %v", err) - } - - // Local state without remote, error! - local := terraform.NewState() - testWriteLocal(t, local) - if err := ValidateConfig(remote); err == nil { - t.Fatalf("local missing remote") - } - - // Local with matching remote, should be fine - local.Remote = remote - testWriteLocal(t, local) - if err := ValidateConfig(remote); err != nil { - t.Fatalf("err: %v", err) - } - - // Local with conflicting remote, not fine - local.Remote = &terraform.RemoteState{ - Name: "whatchutalkingabout", - } - testWriteLocal(t, local) - if err := ValidateConfig(remote); err == nil { - t.Fatalf("conflicting remote") - } -} - func TestRefreshState_Init(t *testing.T) { defer testFixCwd(testDir(t)) remote, srv := testRemote(t, nil)