Terraform: Try to use existing files on partially unpacked workspace

This commit is contained in:
Nils Hanke 2022-11-14 19:15:10 +01:00 committed by Nils Hanke
parent 4a2cba988c
commit e93527144e
2 changed files with 41 additions and 4 deletions

View File

@ -7,8 +7,10 @@ SPDX-License-Identifier: AGPL-3.0-only
package terraform package terraform
import ( import (
"bytes"
"embed" "embed"
"errors" "errors"
"fmt"
"io/fs" "io/fs"
"path" "path"
"path/filepath" "path/filepath"
@ -41,7 +43,24 @@ func prepareWorkspace(fileHandler file.Handler, provider cloudprovider.Provider,
return err return err
} }
fileName := strings.Replace(filepath.Join(workingDir, path), rootDir+"/", "", 1) fileName := strings.Replace(filepath.Join(workingDir, path), rootDir+"/", "", 1)
return fileHandler.Write(fileName, content, file.OptMkdirAll) if err := fileHandler.Write(fileName, content, file.OptMkdirAll); errors.Is(err, afero.ErrFileExists) {
// If a file already exists, check if it is identical. If yes, continue and don't write anything to disk.
// If no, don't overwrite it and instead throw an error. The affected file could be from a different version,
// provider, corrupted or manually modified in general.
existingFileContent, err := fileHandler.Read(fileName)
if err != nil {
return err
}
if !bytes.Equal(content, existingFileContent) {
return fmt.Errorf("trying to overwrite existing Terraform file with different version")
}
return nil
} else if err != nil {
return err
}
return nil
}) })
} }

View File

@ -21,8 +21,9 @@ import (
func TestLoader(t *testing.T) { func TestLoader(t *testing.T) {
testCases := map[string]struct { testCases := map[string]struct {
provider cloudprovider.Provider provider cloudprovider.Provider
fileList []string fileList []string
testAlreadyUnpacked bool
}{ }{
"aws": { "aws": {
provider: cloudprovider.AWS, provider: cloudprovider.AWS,
@ -51,6 +52,16 @@ func TestLoader(t *testing.T) {
"modules", "modules",
}, },
}, },
"continue on (partially) unpacked": {
provider: cloudprovider.AWS,
fileList: []string{
"main.tf",
"variables.tf",
"outputs.tf",
"modules",
},
testAlreadyUnpacked: true,
},
} }
for name, tc := range testCases { for name, tc := range testCases {
@ -62,9 +73,16 @@ func TestLoader(t *testing.T) {
err := prepareWorkspace(file, tc.provider, constants.TerraformWorkingDir) err := prepareWorkspace(file, tc.provider, constants.TerraformWorkingDir)
require.NoError(err) require.NoError(err)
checkFiles(t, file, func(err error) { assert.NoError(err) }, tc.fileList) checkFiles(t, file, func(err error) { assert.NoError(err) }, tc.fileList)
if tc.testAlreadyUnpacked {
// Let's try the same again and check if we don't get a "file already exists" error.
require.NoError(file.Remove(filepath.Join(constants.TerraformWorkingDir, "variables.tf")))
err := prepareWorkspace(file, tc.provider, constants.TerraformWorkingDir)
assert.NoError(err)
checkFiles(t, file, func(err error) { assert.NoError(err) }, tc.fileList)
}
err = cleanUpWorkspace(file, constants.TerraformWorkingDir) err = cleanUpWorkspace(file, constants.TerraformWorkingDir)
require.NoError(err) require.NoError(err)