mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-24 16:10:46 -06:00
OpenTofu Specific Code Override: Add support to .tofu files (#1738)
Signed-off-by: Ronny Orot <ronny.orot@gmail.com>
This commit is contained in:
parent
1ecb2dcae3
commit
ab289fc07c
@ -32,6 +32,9 @@ linters-settings:
|
|||||||
cyclop:
|
cyclop:
|
||||||
max-complexity: 15
|
max-complexity: 15
|
||||||
|
|
||||||
|
gocognit:
|
||||||
|
min-complexity: 50
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
exclude-rules:
|
exclude-rules:
|
||||||
- path: (.+)_test.go
|
- path: (.+)_test.go
|
||||||
|
@ -7,9 +7,11 @@ package configs
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
@ -19,6 +21,17 @@ const (
|
|||||||
DefaultTestDirectory = "tests"
|
DefaultTestDirectory = "tests"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
tfExt = ".tf"
|
||||||
|
tofuExt = ".tofu"
|
||||||
|
tfJSONExt = ".tf.json"
|
||||||
|
tofuJSONExt = ".tofu.json"
|
||||||
|
tfTestExt = ".tftest.hcl"
|
||||||
|
tofuTestExt = ".tofutest.hcl"
|
||||||
|
tfTestJSONExt = ".tftest.json"
|
||||||
|
tofuTestJSONExt = ".tofutest.json"
|
||||||
|
)
|
||||||
|
|
||||||
// LoadConfigDir reads the .tf and .tf.json files in the given directory
|
// LoadConfigDir reads the .tf and .tf.json files in the given directory
|
||||||
// as config files (using LoadConfigFile) and then combines these files into
|
// as config files (using LoadConfigFile) and then combines these files into
|
||||||
// a single Module.
|
// a single Module.
|
||||||
@ -178,7 +191,8 @@ func (p *Parser) dirFiles(dir string, testsDir string) (primary, override, tests
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasSuffix(testInfo.Name(), ".tftest.hcl") || strings.HasSuffix(testInfo.Name(), ".tftest.json") {
|
ext := fileExt(testInfo.Name())
|
||||||
|
if isTestFileExt(ext) {
|
||||||
tests = append(tests, filepath.Join(testPath, testInfo.Name()))
|
tests = append(tests, filepath.Join(testPath, testInfo.Name()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,7 +222,7 @@ func (p *Parser) dirFiles(dir string, testsDir string) (primary, override, tests
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if ext == ".tftest.hcl" || ext == ".tftest.json" {
|
if isTestFileExt(ext) {
|
||||||
if includeTests {
|
if includeTests {
|
||||||
tests = append(tests, filepath.Join(dir, name))
|
tests = append(tests, filepath.Join(dir, name))
|
||||||
}
|
}
|
||||||
@ -226,7 +240,44 @@ func (p *Parser) dirFiles(dir string, testsDir string) (primary, override, tests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return filterTfPathsWithTofuAlternatives(primary), filterTfPathsWithTofuAlternatives(override), filterTfPathsWithTofuAlternatives(tests), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
// filterTfPathsWithTofuAlternatives filters out .tf files if they have an
|
||||||
|
// alternative .tofu file with the same name.
|
||||||
|
// For example, if there are both 'resources.tf.json' and
|
||||||
|
// 'resources.tofu.json' files, the 'resources.tf.json' file will be ignored,
|
||||||
|
// and only the 'resources.tofu.json' file will be returned as a relevant path.
|
||||||
|
func filterTfPathsWithTofuAlternatives(paths []string) []string {
|
||||||
|
var ignoredPaths []string
|
||||||
|
var relevantPaths []string
|
||||||
|
|
||||||
|
for _, p := range paths {
|
||||||
|
ext := tfFileExt(p)
|
||||||
|
|
||||||
|
if ext == "" {
|
||||||
|
relevantPaths = append(relevantPaths, p)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
parallelTofuExt := strings.ReplaceAll(ext, ".tf", ".tofu")
|
||||||
|
pathWithoutExt, _ := strings.CutSuffix(p, ext)
|
||||||
|
parallelTofuPath := pathWithoutExt + parallelTofuExt
|
||||||
|
|
||||||
|
// If the .tf file has a parallel .tofu file in the directory,
|
||||||
|
// we'll ignore the .tf file and only use the .tofu file
|
||||||
|
if slices.Contains(paths, parallelTofuPath) {
|
||||||
|
ignoredPaths = append(ignoredPaths, p)
|
||||||
|
} else {
|
||||||
|
relevantPaths = append(relevantPaths, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ignoredPaths) > 0 {
|
||||||
|
log.Printf("[INFO] filterTfPathsWithTofuAlternatives: Ignored the following .tf files because a .tofu file alternative exists: %q", ignoredPaths)
|
||||||
|
}
|
||||||
|
|
||||||
|
return relevantPaths
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) loadTestFiles(basePath string, paths []string) (map[string]*TestFile, hcl.Diagnostics) {
|
func (p *Parser) loadTestFiles(basePath string, paths []string) (map[string]*TestFile, hcl.Diagnostics) {
|
||||||
@ -258,19 +309,53 @@ func (p *Parser) loadTestFiles(basePath string, paths []string) (map[string]*Tes
|
|||||||
// fileExt returns the OpenTofu configuration extension of the given
|
// fileExt returns the OpenTofu configuration extension of the given
|
||||||
// path, or a blank string if it is not a recognized extension.
|
// path, or a blank string if it is not a recognized extension.
|
||||||
func fileExt(path string) string {
|
func fileExt(path string) string {
|
||||||
if strings.HasSuffix(path, ".tf") {
|
extension := tfFileExt(path)
|
||||||
return ".tf"
|
|
||||||
} else if strings.HasSuffix(path, ".tf.json") {
|
if extension == "" {
|
||||||
return ".tf.json"
|
extension = tofuFileExt(path)
|
||||||
} else if strings.HasSuffix(path, ".tftest.hcl") {
|
}
|
||||||
return ".tftest.hcl"
|
|
||||||
} else if strings.HasSuffix(path, ".tftest.json") {
|
return extension
|
||||||
return ".tftest.json"
|
}
|
||||||
} else {
|
|
||||||
|
// tfFileExt returns the OpenTofu .tf configuration extension of the given
|
||||||
|
// path, or a blank string if it is not a recognized .tf extension.
|
||||||
|
func tfFileExt(path string) string {
|
||||||
|
switch {
|
||||||
|
case strings.HasSuffix(path, tfExt):
|
||||||
|
return tfExt
|
||||||
|
case strings.HasSuffix(path, tfJSONExt):
|
||||||
|
return tfJSONExt
|
||||||
|
case strings.HasSuffix(path, tfTestExt):
|
||||||
|
return tfTestExt
|
||||||
|
case strings.HasSuffix(path, tfTestJSONExt):
|
||||||
|
return tfTestJSONExt
|
||||||
|
default:
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tofuFileExt returns the OpenTofu .tofu configuration extension of the given
|
||||||
|
// path, or a blank string if it is not a recognized .tofu extension.
|
||||||
|
func tofuFileExt(path string) string {
|
||||||
|
switch {
|
||||||
|
case strings.HasSuffix(path, tofuExt):
|
||||||
|
return tofuExt
|
||||||
|
case strings.HasSuffix(path, tofuJSONExt):
|
||||||
|
return tofuJSONExt
|
||||||
|
case strings.HasSuffix(path, tofuTestExt):
|
||||||
|
return tofuTestExt
|
||||||
|
case strings.HasSuffix(path, tofuTestJSONExt):
|
||||||
|
return tofuTestJSONExt
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func isTestFileExt(ext string) bool {
|
||||||
|
return ext == tfTestExt || ext == tfTestJSONExt || ext == tofuTestExt || ext == tofuTestJSONExt
|
||||||
|
}
|
||||||
|
|
||||||
// IsIgnoredFile returns true if the given filename (which must not have a
|
// IsIgnoredFile returns true if the given filename (which must not have a
|
||||||
// directory path ahead of it) should be ignored as e.g. an editor swap file.
|
// directory path ahead of it) should be ignored as e.g. an editor swap file.
|
||||||
func IsIgnoredFile(name string) bool {
|
func IsIgnoredFile(name string) bool {
|
||||||
|
@ -238,6 +238,79 @@ func TestParserLoadConfigDirFailure(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParserLoadConfigDirWithTests_TofuFiles(t *testing.T) {
|
||||||
|
expectedVariablesToOverride := []string{"should_override", "should_override_json"}
|
||||||
|
expectedLoadedTestFiles := []string{"test/resources_test.tofutest.hcl", "test/resources_test_json.tofutest.json"}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
path string
|
||||||
|
expectedResources []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "only .tofu files",
|
||||||
|
path: "testdata/tofu-only-files",
|
||||||
|
expectedResources: []string{"aws_security_group.firewall_tofu", "aws_instance.web_tofu", "test_object.a_tofu", "test_object.b_tofu"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: ".tofu and .tf files",
|
||||||
|
path: "testdata/tofu-and-tf-files",
|
||||||
|
expectedResources: []string{"aws_security_group.firewall_tofu", "aws_instance.web_tofu", "test_object.a_tofu", "test_object.b_tofu", "tf_resource.first", "tf_json_resource.a"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
parser := NewParser(nil)
|
||||||
|
path := tt.path
|
||||||
|
|
||||||
|
mod, diags := parser.LoadConfigDirWithTests(path, "test")
|
||||||
|
if len(diags) != 0 {
|
||||||
|
t.Errorf("unexpected diagnostics")
|
||||||
|
for _, diag := range diags {
|
||||||
|
t.Logf("- %s", diag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if mod.SourceDir != path {
|
||||||
|
t.Errorf("wrong SourceDir value %q; want %s", mod.SourceDir, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(tt.expectedResources) != len(mod.ManagedResources) {
|
||||||
|
t.Errorf("expected to find %d resources but instead got %d resources", len(tt.expectedResources), len(mod.ManagedResources))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, expectedResource := range tt.expectedResources {
|
||||||
|
if mod.ManagedResources[expectedResource] == nil {
|
||||||
|
t.Errorf("expected to load %s resource as part of configuration but it is missing", expectedResource)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(expectedVariablesToOverride) != len(mod.Variables) {
|
||||||
|
t.Errorf("expected to find %d variables but instead got %d resources", len(expectedVariablesToOverride), len(mod.Variables))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, expectedVariable := range expectedVariablesToOverride {
|
||||||
|
variableInConfiguration := mod.Variables[expectedVariable]
|
||||||
|
if variableInConfiguration == nil {
|
||||||
|
t.Errorf("expected to load %s variable as part of configuration but it is missing", expectedVariable)
|
||||||
|
} else if variableInConfiguration.Default.AsString() != "overridden by tofu file" {
|
||||||
|
t.Errorf("expected variable default value %s to be overridden", expectedVariable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(mod.Tests) != 2 {
|
||||||
|
t.Errorf("incorrect number of test files found: %d", len(mod.Tests))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, expectedTest := range expectedLoadedTestFiles {
|
||||||
|
if mod.Tests[expectedTest] == nil {
|
||||||
|
t.Errorf("expected to load %s test as part of configuration but it is missing", expectedTest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestIsEmptyDir(t *testing.T) {
|
func TestIsEmptyDir(t *testing.T) {
|
||||||
val, err := IsEmptyDir(filepath.Join("testdata", "valid-files"))
|
val, err := IsEmptyDir(filepath.Join("testdata", "valid-files"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
3
internal/configs/testdata/tofu-and-tf-files/more-resources.tf
vendored
Normal file
3
internal/configs/testdata/tofu-and-tf-files/more-resources.tf
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
resource "tf_resource" "first" {
|
||||||
|
test_string = "hello"
|
||||||
|
}
|
10
internal/configs/testdata/tofu-and-tf-files/more-resources.tf.json
vendored
Normal file
10
internal/configs/testdata/tofu-and-tf-files/more-resources.tf.json
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"resource": {
|
||||||
|
"tf_json_resource": {
|
||||||
|
"a": {
|
||||||
|
"count": 1,
|
||||||
|
"test_string": "first"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
internal/configs/testdata/tofu-and-tf-files/resources.tf
vendored
Normal file
43
internal/configs/testdata/tofu-and-tf-files/resources.tf
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
resource "aws_security_group" "firewall" {
|
||||||
|
lifecycle {
|
||||||
|
create_before_destroy = true
|
||||||
|
prevent_destroy = true
|
||||||
|
ignore_changes = [
|
||||||
|
description,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
connection {
|
||||||
|
host = "127.0.0.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
provisioner "local-exec" {
|
||||||
|
command = "echo hello"
|
||||||
|
|
||||||
|
connection {
|
||||||
|
host = "10.1.2.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
provisioner "local-exec" {
|
||||||
|
command = "echo hello"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_instance" "web" {
|
||||||
|
count = 2
|
||||||
|
ami = "ami-1234"
|
||||||
|
security_groups = [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
|
||||||
|
network_interface {
|
||||||
|
device_index = 0
|
||||||
|
description = "Main network interface"
|
||||||
|
}
|
||||||
|
|
||||||
|
depends_on = [
|
||||||
|
aws_security_group.firewall,
|
||||||
|
]
|
||||||
|
}
|
14
internal/configs/testdata/tofu-and-tf-files/resources.tf.json
vendored
Normal file
14
internal/configs/testdata/tofu-and-tf-files/resources.tf.json
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"resource": {
|
||||||
|
"test_object": {
|
||||||
|
"a": {
|
||||||
|
"count": 1,
|
||||||
|
"test_string": "hello"
|
||||||
|
},
|
||||||
|
"b": {
|
||||||
|
"count": 1,
|
||||||
|
"test_string": "world"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
internal/configs/testdata/tofu-and-tf-files/resources.tofu
vendored
Normal file
43
internal/configs/testdata/tofu-and-tf-files/resources.tofu
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
resource "aws_security_group" "firewall_tofu" {
|
||||||
|
lifecycle {
|
||||||
|
create_before_destroy = true
|
||||||
|
prevent_destroy = true
|
||||||
|
ignore_changes = [
|
||||||
|
description,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
connection {
|
||||||
|
host = "127.0.0.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
provisioner "local-exec" {
|
||||||
|
command = "echo hello"
|
||||||
|
|
||||||
|
connection {
|
||||||
|
host = "10.1.2.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
provisioner "local-exec" {
|
||||||
|
command = "echo hello"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_instance" "web_tofu" {
|
||||||
|
count = 2
|
||||||
|
ami = "ami-1234"
|
||||||
|
security_groups = [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
|
||||||
|
network_interface {
|
||||||
|
device_index = 0
|
||||||
|
description = "Main network interface"
|
||||||
|
}
|
||||||
|
|
||||||
|
depends_on = [
|
||||||
|
aws_security_group.firewall,
|
||||||
|
]
|
||||||
|
}
|
14
internal/configs/testdata/tofu-and-tf-files/resources.tofu.json
vendored
Normal file
14
internal/configs/testdata/tofu-and-tf-files/resources.tofu.json
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"resource": {
|
||||||
|
"test_object": {
|
||||||
|
"a_tofu": {
|
||||||
|
"count": 1,
|
||||||
|
"test_string": "hello"
|
||||||
|
},
|
||||||
|
"b_tofu": {
|
||||||
|
"count": 1,
|
||||||
|
"test_string": "world"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
internal/configs/testdata/tofu-and-tf-files/test/resources_test.tftest.hcl
vendored
Normal file
27
internal/configs/testdata/tofu-and-tf-files/test/resources_test.tftest.hcl
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# test_run_one runs a partial plan
|
||||||
|
run "test_run_one" {
|
||||||
|
command = plan
|
||||||
|
|
||||||
|
plan_options {
|
||||||
|
target = [
|
||||||
|
test_object.b
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = test_object.b.test_string == "world"
|
||||||
|
error_message = "invalid value"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# test_run_two does a complete apply operation
|
||||||
|
run "test_run_two" {
|
||||||
|
variables {
|
||||||
|
input = "custom"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = test_object.a.test_string == "hello"
|
||||||
|
error_message = "invalid value"
|
||||||
|
}
|
||||||
|
}
|
27
internal/configs/testdata/tofu-and-tf-files/test/resources_test.tofutest.hcl
vendored
Normal file
27
internal/configs/testdata/tofu-and-tf-files/test/resources_test.tofutest.hcl
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# test_run_one runs a partial plan
|
||||||
|
run "test_run_one" {
|
||||||
|
command = plan
|
||||||
|
|
||||||
|
plan_options {
|
||||||
|
target = [
|
||||||
|
test_object.b
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = test_object.b.test_string == "world"
|
||||||
|
error_message = "invalid value"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# test_run_two does a complete apply operation
|
||||||
|
run "test_run_two" {
|
||||||
|
variables {
|
||||||
|
input = "custom"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = test_object.a.test_string == "hello"
|
||||||
|
error_message = "invalid value"
|
||||||
|
}
|
||||||
|
}
|
29
internal/configs/testdata/tofu-and-tf-files/test/resources_test_json.tftest.json
vendored
Normal file
29
internal/configs/testdata/tofu-and-tf-files/test/resources_test_json.tftest.json
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"variables": {
|
||||||
|
"input": "default"
|
||||||
|
},
|
||||||
|
"run": {
|
||||||
|
"test_run_one": {
|
||||||
|
"command": "plan",
|
||||||
|
"plan_options": {
|
||||||
|
"target": [
|
||||||
|
"test_object.a"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"assert": [
|
||||||
|
{
|
||||||
|
"condition": "${test_object.a.test_string} == hello",
|
||||||
|
"error_message": "invalid value"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"test_run_two": {
|
||||||
|
"assert": [
|
||||||
|
{
|
||||||
|
"condition": "${test_object.b.test_string} == world",
|
||||||
|
"error_message": "invalid value"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
internal/configs/testdata/tofu-and-tf-files/test/resources_test_json.tofutest.json
vendored
Normal file
29
internal/configs/testdata/tofu-and-tf-files/test/resources_test_json.tofutest.json
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"variables": {
|
||||||
|
"input": "default"
|
||||||
|
},
|
||||||
|
"run": {
|
||||||
|
"test_run_one": {
|
||||||
|
"command": "plan",
|
||||||
|
"plan_options": {
|
||||||
|
"target": [
|
||||||
|
"test_object.a"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"assert": [
|
||||||
|
{
|
||||||
|
"condition": "${test_object.a.test_string} == hello",
|
||||||
|
"error_message": "invalid value"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"test_run_two": {
|
||||||
|
"assert": [
|
||||||
|
{
|
||||||
|
"condition": "${test_object.b.test_string} == world",
|
||||||
|
"error_message": "invalid value"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
internal/configs/testdata/tofu-and-tf-files/variables.tf
vendored
Normal file
3
internal/configs/testdata/tofu-and-tf-files/variables.tf
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
variable "should_override" {
|
||||||
|
default = "not overridden"
|
||||||
|
}
|
7
internal/configs/testdata/tofu-and-tf-files/variables.tf.json
vendored
Normal file
7
internal/configs/testdata/tofu-and-tf-files/variables.tf.json
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variable": {
|
||||||
|
"should_override_json": {
|
||||||
|
"default": "not overridden"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
internal/configs/testdata/tofu-and-tf-files/variables_override.tf
vendored
Normal file
3
internal/configs/testdata/tofu-and-tf-files/variables_override.tf
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
variable "should_override" {
|
||||||
|
default = "overridden by tf file"
|
||||||
|
}
|
7
internal/configs/testdata/tofu-and-tf-files/variables_override.tf.json
vendored
Normal file
7
internal/configs/testdata/tofu-and-tf-files/variables_override.tf.json
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variable": {
|
||||||
|
"should_override_json": {
|
||||||
|
"default": "overridden by tf file"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
internal/configs/testdata/tofu-and-tf-files/variables_override.tofu
vendored
Normal file
3
internal/configs/testdata/tofu-and-tf-files/variables_override.tofu
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
variable "should_override" {
|
||||||
|
default = "overridden by tofu file"
|
||||||
|
}
|
7
internal/configs/testdata/tofu-and-tf-files/variables_override.tofu.json
vendored
Normal file
7
internal/configs/testdata/tofu-and-tf-files/variables_override.tofu.json
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variable": {
|
||||||
|
"should_override_json": {
|
||||||
|
"default": "overridden by tofu file"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
internal/configs/testdata/tofu-only-files/resources.tofu
vendored
Normal file
43
internal/configs/testdata/tofu-only-files/resources.tofu
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
resource "aws_security_group" "firewall_tofu" {
|
||||||
|
lifecycle {
|
||||||
|
create_before_destroy = true
|
||||||
|
prevent_destroy = true
|
||||||
|
ignore_changes = [
|
||||||
|
description,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
connection {
|
||||||
|
host = "127.0.0.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
provisioner "local-exec" {
|
||||||
|
command = "echo hello"
|
||||||
|
|
||||||
|
connection {
|
||||||
|
host = "10.1.2.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
provisioner "local-exec" {
|
||||||
|
command = "echo hello"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_instance" "web_tofu" {
|
||||||
|
count = 2
|
||||||
|
ami = "ami-1234"
|
||||||
|
security_groups = [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
|
||||||
|
network_interface {
|
||||||
|
device_index = 0
|
||||||
|
description = "Main network interface"
|
||||||
|
}
|
||||||
|
|
||||||
|
depends_on = [
|
||||||
|
aws_security_group.firewall,
|
||||||
|
]
|
||||||
|
}
|
14
internal/configs/testdata/tofu-only-files/resources.tofu.json
vendored
Normal file
14
internal/configs/testdata/tofu-only-files/resources.tofu.json
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"resource": {
|
||||||
|
"test_object": {
|
||||||
|
"a_tofu": {
|
||||||
|
"count": 1,
|
||||||
|
"test_string": "hello"
|
||||||
|
},
|
||||||
|
"b_tofu": {
|
||||||
|
"count": 1,
|
||||||
|
"test_string": "world"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
internal/configs/testdata/tofu-only-files/test/resources_test.tofutest.hcl
vendored
Normal file
27
internal/configs/testdata/tofu-only-files/test/resources_test.tofutest.hcl
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# test_run_one runs a partial plan
|
||||||
|
run "test_run_one" {
|
||||||
|
command = plan
|
||||||
|
|
||||||
|
plan_options {
|
||||||
|
target = [
|
||||||
|
test_object.b
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = test_object.b.test_string == "world"
|
||||||
|
error_message = "invalid value"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# test_run_two does a complete apply operation
|
||||||
|
run "test_run_two" {
|
||||||
|
variables {
|
||||||
|
input = "custom"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = test_object.a.test_string == "hello"
|
||||||
|
error_message = "invalid value"
|
||||||
|
}
|
||||||
|
}
|
29
internal/configs/testdata/tofu-only-files/test/resources_test_json.tofutest.json
vendored
Normal file
29
internal/configs/testdata/tofu-only-files/test/resources_test_json.tofutest.json
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"variables": {
|
||||||
|
"input": "default"
|
||||||
|
},
|
||||||
|
"run": {
|
||||||
|
"test_run_one": {
|
||||||
|
"command": "plan",
|
||||||
|
"plan_options": {
|
||||||
|
"target": [
|
||||||
|
"test_object.a"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"assert": [
|
||||||
|
{
|
||||||
|
"condition": "${test_object.a.test_string} == hello",
|
||||||
|
"error_message": "invalid value"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"test_run_two": {
|
||||||
|
"assert": [
|
||||||
|
{
|
||||||
|
"condition": "${test_object.b.test_string} == world",
|
||||||
|
"error_message": "invalid value"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
internal/configs/testdata/tofu-only-files/variables.tofu
vendored
Normal file
3
internal/configs/testdata/tofu-only-files/variables.tofu
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
variable "should_override" {
|
||||||
|
default = "not overridden"
|
||||||
|
}
|
7
internal/configs/testdata/tofu-only-files/variables.tofu.json
vendored
Normal file
7
internal/configs/testdata/tofu-only-files/variables.tofu.json
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variable": {
|
||||||
|
"should_override_json": {
|
||||||
|
"default": "not overridden"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
internal/configs/testdata/tofu-only-files/variables_override.tofu
vendored
Normal file
3
internal/configs/testdata/tofu-only-files/variables_override.tofu
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
variable "should_override" {
|
||||||
|
default = "overridden by tofu file"
|
||||||
|
}
|
7
internal/configs/testdata/tofu-only-files/variables_override.tofu.json
vendored
Normal file
7
internal/configs/testdata/tofu-only-files/variables_override.tofu.json
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variable": {
|
||||||
|
"should_override_json": {
|
||||||
|
"default": "overridden by tofu file"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user