Skip to content

Commit

Permalink
backend: StateMgrWithoutCheckVersion
Browse files Browse the repository at this point in the history
Allow users of backends to initialize a state manager instance without
checking the Terraform version of any state files which are retrieved
during this process. Many backends call RefreshState as part of
initialization, and this new method instead calls the new
RefreshStateWithoutCheckVersion method to prevent version checking.
  • Loading branch information
alisdair committed Oct 26, 2020
1 parent 06af227 commit c8d7515
Show file tree
Hide file tree
Showing 21 changed files with 228 additions and 28 deletions.
4 changes: 4 additions & 0 deletions backend/atlas/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
return &remote.State{Client: b.stateClient}, nil
}

func (b *Backend) StateMgrWithoutCheckVersion(name string) (statemgr.Full, error) {
return b.StateMgr(name)
}

// Colorize returns the Colorize structure that can be used for colorizing
// output. This is gauranteed to always return a non-nil value and so is useful
// as a helper to wrap any potentially colored strings.
Expand Down
12 changes: 12 additions & 0 deletions backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,18 @@ type Backend interface {
// PersistState is called, depending on the state manager implementation.
StateMgr(workspace string) (statemgr.Full, error)

// StateMgrWithoutCheckVersion returns the state manager for the given
// workspace name, while ensuring that Terraform version checks are not
// performed if the backend needs to read a state file in order to
// initialize the state manager.
//
// For backends which do not need to read a state file at this point, this
// is identical to StateMgr.
//
// This is used to facilitate reading compatible state files from newer
// versions of Terraform.
StateMgrWithoutCheckVersion(workspace string) (statemgr.Full, error)

// DeleteWorkspace removes the workspace with the given name if it exists.
//
// DeleteWorkspace cannot prevent deleting a state that is in use. It is
Expand Down
4 changes: 4 additions & 0 deletions backend/local/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,10 @@ func (b *Local) StateMgr(name string) (statemgr.Full, error) {
return s, nil
}

func (b *Local) StateMgrWithoutCheckVersion(name string) (statemgr.Full, error) {
return b.StateMgr(name)
}

// Operation implements backend.Enhanced
//
// This will initialize an in-memory terraform.Context to perform the
Expand Down
4 changes: 4 additions & 0 deletions backend/nil.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ func (Nil) StateMgr(string) (statemgr.Full, error) {
return statemgr.NewFullFake(statemgr.NewTransientInMemory(nil), nil), nil
}

func (Nil) StateMgrWithoutCheckVersion(string) (statemgr.Full, error) {
return statemgr.NewFullFake(statemgr.NewTransientInMemory(nil), nil), nil
}

func (Nil) DeleteWorkspace(string) error {
return nil
}
Expand Down
4 changes: 4 additions & 0 deletions backend/remote-state/artifactory/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,7 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
Client: b.client,
}, nil
}

func (b *Backend) StateMgrWithoutCheckVersion(name string) (statemgr.Full, error) {
return b.StateMgr(name)
}
21 changes: 18 additions & 3 deletions backend/remote-state/azure/backend_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ func (b *Backend) DeleteWorkspace(name string) error {
}

func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
return b.stateMgr(name, true)
}

func (b *Backend) StateMgrWithoutCheckVersion(name string) (statemgr.Full, error) {
return b.stateMgr(name, false)
}

func (b *Backend) stateMgr(name string, checkVersion bool) (statemgr.Full, error) {
ctx := context.TODO()
blobClient, err := b.armClient.getBlobClient(ctx)
if err != nil {
Expand Down Expand Up @@ -115,9 +123,16 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
}

// Grab the value
if err := stateMgr.RefreshState(); err != nil {
err = lockUnlock(err)
return nil, err
if checkVersion {
if err := stateMgr.RefreshState(); err != nil {
err = lockUnlock(err)
return nil, err
}
} else {
if err := stateMgr.RefreshStateWithoutCheckVersion(); err != nil {
err = lockUnlock(err)
return nil, err
}
}

// If we have no state, we have to create an empty state
Expand Down
21 changes: 18 additions & 3 deletions backend/remote-state/consul/backend_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ func (b *Backend) DeleteWorkspace(name string) error {
}

func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
return b.stateMgr(name, true)
}

func (b *Backend) StateMgrWithoutCheckVersion(name string) (statemgr.Full, error) {
return b.stateMgr(name, false)
}

func (b *Backend) stateMgr(name string, checkVersion bool) (statemgr.Full, error) {
// Determine the path of the data
path := b.path(name)

Expand Down Expand Up @@ -109,9 +117,16 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
}

// Grab the value
if err := stateMgr.RefreshState(); err != nil {
err = lockUnlock(err)
return nil, err
if checkVersion {
if err := stateMgr.RefreshState(); err != nil {
err = lockUnlock(err)
return nil, err
}
} else {
if err := stateMgr.RefreshStateWithoutCheckVersion(); err != nil {
err = lockUnlock(err)
return nil, err
}
}

// If we have no state, we have to create an empty state
Expand Down
21 changes: 18 additions & 3 deletions backend/remote-state/cos/backend_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ func (b *Backend) DeleteWorkspace(name string) error {

// StateMgr manage the state, if the named state not exists, a new file will created
func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
return b.stateMgr(name, true)
}

func (b *Backend) StateMgrWithoutCheckVersion(name string) (statemgr.Full, error) {
return b.stateMgr(name, false)
}

func (b *Backend) stateMgr(name string, checkVersion bool) (statemgr.Full, error) {
log.Printf("[DEBUG] state manager, current workspace: %v", name)

c, err := b.client(name)
Expand Down Expand Up @@ -108,9 +116,16 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
}

// Grab the value
if err := stateMgr.RefreshState(); err != nil {
err = lockUnlock(err)
return nil, err
if checkVersion {
if err := stateMgr.RefreshState(); err != nil {
err = lockUnlock(err)
return nil, err
}
} else {
if err := stateMgr.RefreshStateWithoutCheckVersion(); err != nil {
err = lockUnlock(err)
return nil, err
}
}

// If we have no state, we have to create an empty state
Expand Down
4 changes: 4 additions & 0 deletions backend/remote-state/etcdv2/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,7 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
},
}, nil
}

func (b *Backend) StateMgrWithoutCheckVersion(name string) (statemgr.Full, error) {
return b.StateMgr(name)
}
21 changes: 18 additions & 3 deletions backend/remote-state/etcdv3/backend_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ func (b *Backend) DeleteWorkspace(name string) error {
}

func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
return b.stateMgr(name, true)
}

func (b *Backend) StateMgrWithoutCheckVersion(name string) (statemgr.Full, error) {
return b.stateMgr(name, false)
}

func (b *Backend) stateMgr(name string, checkVersion bool) (statemgr.Full, error) {
var stateMgr statemgr.Full = &remote.State{
Client: &RemoteClient{
Client: b.client,
Expand All @@ -68,9 +76,16 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
return parent
}

if err := stateMgr.RefreshState(); err != nil {
err = lockUnlock(err)
return nil, err
if checkVersion {
if err := stateMgr.RefreshState(); err != nil {
err = lockUnlock(err)
return nil, err
}
} else {
if err := stateMgr.RefreshStateWithoutCheckVersion(); err != nil {
err = lockUnlock(err)
return nil, err
}
}

if v := stateMgr.State(); v == nil {
Expand Down
18 changes: 16 additions & 2 deletions backend/remote-state/gcs/backend_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ func (b *Backend) client(name string) (*remoteClient, error) {
// StateMgr reads and returns the named state from GCS. If the named state does
// not yet exist, a new state file is created.
func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
return b.stateMgr(name, true)
}

func (b *Backend) StateMgrWithoutCheckVersion(name string) (statemgr.Full, error) {
return b.stateMgr(name, false)
}

func (b *Backend) stateMgr(name string, checkVersion bool) (statemgr.Full, error) {
c, err := b.client(name)
if err != nil {
return nil, err
Expand All @@ -95,8 +103,14 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
st := &remote.State{Client: c}

// Grab the value
if err := st.RefreshState(); err != nil {
return nil, err
if checkVersion {
if err := st.RefreshState(); err != nil {
return nil, err
}
} else {
if err := st.RefreshStateWithoutCheckVersion(); err != nil {
return nil, err
}
}

// If we have no state, we have to create an empty state
Expand Down
4 changes: 4 additions & 0 deletions backend/remote-state/http/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
return &remote.State{Client: b.client}, nil
}

func (b *Backend) StateMgrWithoutCheckVersion(name string) (statemgr.Full, error) {
return b.StateMgr(name)
}

func (b *Backend) Workspaces() ([]string, error) {
return nil, backend.ErrWorkspacesNotSupported
}
Expand Down
4 changes: 4 additions & 0 deletions backend/remote-state/inmem/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
return s, nil
}

func (b *Backend) StateMgrWithoutCheckVersion(name string) (statemgr.Full, error) {
return b.StateMgr(name)
}

type stateMap struct {
sync.Mutex
m map[string]*remote.State
Expand Down
18 changes: 16 additions & 2 deletions backend/remote-state/kubernetes/backend_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ func (b *Backend) DeleteWorkspace(name string) error {
}

func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
return b.stateMgr(name, true)
}

func (b *Backend) StateMgrWithoutCheckVersion(name string) (statemgr.Full, error) {
return b.stateMgr(name, false)
}

func (b *Backend) stateMgr(name string, checkVersion bool) (statemgr.Full, error) {
c, err := b.remoteClient(name)
if err != nil {
return nil, err
Expand All @@ -80,8 +88,14 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
stateMgr := &remote.State{Client: c}

// Grab the value
if err := stateMgr.RefreshState(); err != nil {
return nil, err
if checkVersion {
if err := stateMgr.RefreshState(); err != nil {
return nil, err
}
} else {
if err := stateMgr.RefreshStateWithoutCheckVersion(); err != nil {
return nil, err
}
}

// If we have no state, we have to create an empty state
Expand Down
21 changes: 18 additions & 3 deletions backend/remote-state/manta/backend_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ func (b *Backend) DeleteWorkspace(name string) error {
}

func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
return b.stateMgr(name, true)
}

func (b *Backend) StateMgrWithoutCheckVersion(name string) (statemgr.Full, error) {
return b.stateMgr(name, false)
}

func (b *Backend) stateMgr(name string, checkVersion bool) (statemgr.Full, error) {
if name == "" {
return nil, errors.New("missing state name")
}
Expand Down Expand Up @@ -97,9 +105,16 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
}

// Grab the value
if err := stateMgr.RefreshState(); err != nil {
err = lockUnlock(err)
return nil, err
if checkVersion {
if err := stateMgr.RefreshState(); err != nil {
err = lockUnlock(err)
return nil, err
}
} else {
if err := stateMgr.RefreshStateWithoutCheckVersion(); err != nil {
err = lockUnlock(err)
return nil, err
}
}

// If we have no state, we have to create an empty state
Expand Down
21 changes: 18 additions & 3 deletions backend/remote-state/oss/backend_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@ func (b *Backend) DeleteWorkspace(name string) error {
}

func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
return b.stateMgr(name, true)
}

func (b *Backend) StateMgrWithoutCheckVersion(name string) (statemgr.Full, error) {
return b.stateMgr(name, false)
}

func (b *Backend) stateMgr(name string, checkVersion bool) (statemgr.Full, error) {
client, err := b.remoteClient(name)
if err != nil {
return nil, err
Expand Down Expand Up @@ -147,9 +155,16 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
}

// Grab the value
if err := stateMgr.RefreshState(); err != nil {
err = lockUnlock(err)
return nil, err
if checkVersion {
if err := stateMgr.RefreshState(); err != nil {
err = lockUnlock(err)
return nil, err
}
} else {
if err := stateMgr.RefreshStateWithoutCheckVersion(); err != nil {
err = lockUnlock(err)
return nil, err
}
}

// If we have no state, we have to create an empty state
Expand Down
4 changes: 4 additions & 0 deletions backend/remote-state/pg/backend_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,7 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {

return stateMgr, nil
}

func (b *Backend) StateMgrWithoutCheckVersion(name string) (statemgr.Full, error) {
return b.StateMgr(name)
}
Loading

0 comments on commit c8d7515

Please sign in to comment.