Merge pull request #27199 from hashicorp/alisdair/remote-backend-version-latest
backend/remote: Fix for "latest" workspace version
This commit is contained in:
commit
30126baff4
|
@ -641,7 +641,10 @@ func (b *Remote) StateMgr(name string) (statemgr.Full, error) {
|
||||||
// accidentally upgrade state with a new code path, and the version check
|
// accidentally upgrade state with a new code path, and the version check
|
||||||
// logic is coarser and simpler.
|
// logic is coarser and simpler.
|
||||||
if !b.ignoreVersionConflict {
|
if !b.ignoreVersionConflict {
|
||||||
if workspace.TerraformVersion != tfversion.String() {
|
wsv := workspace.TerraformVersion
|
||||||
|
// Explicitly ignore the pseudo-version "latest" here, as it will cause
|
||||||
|
// plan and apply to always fail.
|
||||||
|
if wsv != tfversion.String() && wsv != "latest" {
|
||||||
return nil, fmt.Errorf("Remote workspace Terraform version %q does not match local Terraform version %q", workspace.TerraformVersion, tfversion.String())
|
return nil, fmt.Errorf("Remote workspace Terraform version %q does not match local Terraform version %q", workspace.TerraformVersion, tfversion.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -890,6 +893,13 @@ func (b *Remote) VerifyWorkspaceTerraformVersion(workspaceName string) tfdiags.D
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the workspace has the pseudo-version "latest", all bets are off. We
|
||||||
|
// cannot reasonably determine what the intended Terraform version is, so
|
||||||
|
// we'll skip version verification.
|
||||||
|
if workspace.TerraformVersion == "latest" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
remoteVersion, err := version.NewSemver(workspace.TerraformVersion)
|
remoteVersion, err := version.NewSemver(workspace.TerraformVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
diags = diags.Append(tfdiags.Sourceless(
|
diags = diags.Append(tfdiags.Sourceless(
|
||||||
|
|
|
@ -515,6 +515,45 @@ func TestRemote_StateMgr_versionCheck(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRemote_StateMgr_versionCheckLatest(t *testing.T) {
|
||||||
|
b, bCleanup := testBackendDefault(t)
|
||||||
|
defer bCleanup()
|
||||||
|
|
||||||
|
v0140 := version.Must(version.NewSemver("0.14.0"))
|
||||||
|
|
||||||
|
// Save original local version state and restore afterwards
|
||||||
|
p := tfversion.Prerelease
|
||||||
|
v := tfversion.Version
|
||||||
|
s := tfversion.SemVer
|
||||||
|
defer func() {
|
||||||
|
tfversion.Prerelease = p
|
||||||
|
tfversion.Version = v
|
||||||
|
tfversion.SemVer = s
|
||||||
|
}()
|
||||||
|
|
||||||
|
// For this test, the local Terraform version is set to 0.14.0
|
||||||
|
tfversion.Prerelease = ""
|
||||||
|
tfversion.Version = v0140.String()
|
||||||
|
tfversion.SemVer = v0140
|
||||||
|
|
||||||
|
// Update the remote workspace to the pseudo-version "latest"
|
||||||
|
if _, err := b.client.Workspaces.Update(
|
||||||
|
context.Background(),
|
||||||
|
b.organization,
|
||||||
|
b.workspace,
|
||||||
|
tfe.WorkspaceUpdateOptions{
|
||||||
|
TerraformVersion: tfe.String("latest"),
|
||||||
|
},
|
||||||
|
); err != nil {
|
||||||
|
t.Fatalf("error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should succeed despite not being a string match
|
||||||
|
if _, err := b.StateMgr(backend.DefaultStateName); err != nil {
|
||||||
|
t.Fatalf("expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRemote_VerifyWorkspaceTerraformVersion(t *testing.T) {
|
func TestRemote_VerifyWorkspaceTerraformVersion(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
local string
|
local string
|
||||||
|
@ -528,6 +567,7 @@ func TestRemote_VerifyWorkspaceTerraformVersion(t *testing.T) {
|
||||||
{"0.14.0", "1.1.0", true},
|
{"0.14.0", "1.1.0", true},
|
||||||
{"1.2.0", "1.2.99", false},
|
{"1.2.0", "1.2.99", false},
|
||||||
{"1.2.0", "1.3.0", true},
|
{"1.2.0", "1.3.0", true},
|
||||||
|
{"0.15.0", "latest", false},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(fmt.Sprintf("local %s, remote %s", tc.local, tc.remote), func(t *testing.T) {
|
t.Run(fmt.Sprintf("local %s, remote %s", tc.local, tc.remote), func(t *testing.T) {
|
||||||
|
@ -535,7 +575,6 @@ func TestRemote_VerifyWorkspaceTerraformVersion(t *testing.T) {
|
||||||
defer bCleanup()
|
defer bCleanup()
|
||||||
|
|
||||||
local := version.Must(version.NewSemver(tc.local))
|
local := version.Must(version.NewSemver(tc.local))
|
||||||
remote := version.Must(version.NewSemver(tc.remote))
|
|
||||||
|
|
||||||
// Save original local version state and restore afterwards
|
// Save original local version state and restore afterwards
|
||||||
p := tfversion.Prerelease
|
p := tfversion.Prerelease
|
||||||
|
@ -559,7 +598,7 @@ func TestRemote_VerifyWorkspaceTerraformVersion(t *testing.T) {
|
||||||
b.organization,
|
b.organization,
|
||||||
b.workspace,
|
b.workspace,
|
||||||
tfe.WorkspaceUpdateOptions{
|
tfe.WorkspaceUpdateOptions{
|
||||||
TerraformVersion: tfe.String(remote.String()),
|
TerraformVersion: tfe.String(tc.remote),
|
||||||
},
|
},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
t.Fatalf("error: %v", err)
|
t.Fatalf("error: %v", err)
|
||||||
|
|
Loading…
Reference in New Issue