mirror of
https://github.com/opentofu/opentofu.git
synced 2025-01-04 13:17:43 -06:00
adb88eaa16
In order to properly migrate the contents of resource, data, provider and provisioner blocks we will need the provider's schema in order to understand what is expected, so we can resolve some ambiguities inherent in the legacy HCL AST. This includes an initial prototype of migrating the content of resource blocks just to verify that the information is being gathered correctly. As with the rest of the upgrade_native.go file, this will be reorganized significantly once the basic end-to-end flow is established and we can see how to organize this code better.
122 lines
3.9 KiB
Go
122 lines
3.9 KiB
Go
package configupgrade
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
|
|
"github.com/hashicorp/terraform/tfdiags"
|
|
|
|
hcl2 "github.com/hashicorp/hcl2/hcl"
|
|
hcl2write "github.com/hashicorp/hcl2/hclwrite"
|
|
)
|
|
|
|
// Upgrade takes some input module sources and produces a new ModuleSources
|
|
// that should be equivalent to the input but use the configuration idioms
|
|
// associated with the new configuration loader.
|
|
//
|
|
// The result of this function will probably not be accepted by this function,
|
|
// because it will contain constructs that are known only to the new
|
|
// loader.
|
|
//
|
|
// The result may include additional files that were not present in the
|
|
// input. The result may also include nil entries for filenames that were
|
|
// present in the input, indicating that these files should be deleted.
|
|
// In particular, file renames are represented as a new entry accompanied
|
|
// by a nil entry for the old name.
|
|
//
|
|
// If the returned diagnostics contains errors, the caller should not write
|
|
// the resulting sources to disk since they will probably be incomplete. If
|
|
// only warnings are present then the files may be written to disk. Most
|
|
// warnings are also represented as "TF-UPGRADE-TODO:" comments in the
|
|
// generated source files so that users can visit them all and decide what to
|
|
// do with them.
|
|
func (u *Upgrader) Upgrade(input ModuleSources) (ModuleSources, tfdiags.Diagnostics) {
|
|
ret := make(ModuleSources)
|
|
var diags tfdiags.Diagnostics
|
|
|
|
an, err := u.analyze(input)
|
|
if err != nil {
|
|
diags = diags.Append(err)
|
|
return ret, diags
|
|
}
|
|
|
|
for name, src := range input {
|
|
ext := fileExt(name)
|
|
if ext == "" {
|
|
// This should never happen because we ignore files that don't
|
|
// have our conventional extensions during LoadModule, but we'll
|
|
// silently pass through such files assuming that the caller
|
|
// has been tampering with the sources map somehow.
|
|
ret[name] = src
|
|
continue
|
|
}
|
|
|
|
isJSON := (ext == ".tf.json")
|
|
|
|
// The legacy loader allowed JSON syntax inside files named just .tf,
|
|
// so we'll detect that case and rename them here so that the new
|
|
// loader will accept the JSON. However, JSON files are usually
|
|
// generated so we'll also generate a warning to the user to update
|
|
// whatever program generated the file to use the new name.
|
|
if !isJSON {
|
|
trimSrc := bytes.TrimSpace(src)
|
|
if len(trimSrc) > 0 && (trimSrc[0] == '{' || trimSrc[0] == '[') {
|
|
isJSON = true
|
|
|
|
// Rename in the output
|
|
ret[name] = nil // mark for deletion
|
|
oldName := name
|
|
name = input.UnusedFilename(name + ".json")
|
|
ret[name] = src
|
|
|
|
diags = diags.Append(&hcl2.Diagnostic{
|
|
Severity: hcl2.DiagWarning,
|
|
Summary: "JSON configuration file was renamed",
|
|
Detail: fmt.Sprintf(
|
|
"The file %q appears to be in JSON format, so it was renamed to %q. If this file is generated by another program, that program must be updated to use this new name.",
|
|
oldName, name,
|
|
),
|
|
})
|
|
continue
|
|
}
|
|
}
|
|
|
|
if isJSON {
|
|
// We don't do any automatic rewriting for JSON files, since they
|
|
// are usually generated and thus it's the generating program that
|
|
// needs to be updated, rather than its output.
|
|
diags = diags.Append(&hcl2.Diagnostic{
|
|
Severity: hcl2.DiagWarning,
|
|
Summary: "JSON configuration file was not rewritten",
|
|
Detail: fmt.Sprintf(
|
|
"The JSON configuration file %q was skipped, because JSON files are assumed to be generated. The program that generated this file may need to be updated for changes to the configuration language.",
|
|
name,
|
|
),
|
|
})
|
|
continue
|
|
}
|
|
|
|
// TODO: Actually rewrite this .tf file.
|
|
result, fileDiags := u.upgradeNativeSyntaxFile(name, src, an)
|
|
diags = diags.Append(fileDiags)
|
|
if fileDiags.HasErrors() {
|
|
// Leave unchanged, then.
|
|
ret[name] = src
|
|
continue
|
|
}
|
|
|
|
ret[name] = hcl2write.Format(result.Content)
|
|
}
|
|
|
|
versionsName := ret.UnusedFilename("versions.tf")
|
|
ret[versionsName] = []byte(newVersionConstraint)
|
|
|
|
return ret, diags
|
|
}
|
|
|
|
const newVersionConstraint = `
|
|
terraform {
|
|
required_version = ">= 0.12"
|
|
}
|
|
`
|