Ephemeral write only attributes (#3171)

Signed-off-by: Andrei Ciobanu <andrei.ciobanu@opentofu.org>
Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
This commit is contained in:
Andrei Ciobanu
2025-08-25 13:57:11 +03:00
committed by Christian Mesh
parent cbe16d3a5d
commit 7f76707dd0
29 changed files with 2389 additions and 89 deletions

View File

@@ -6,6 +6,8 @@
package renderers
import (
"maps"
"slices"
"sort"
"testing"
@@ -42,6 +44,18 @@ func ValidatePrimitive(before, after interface{}, action plans.Action, replace b
}
}
func ValidateWriteOnly(action plans.Action, replace bool) ValidateDiffFunction {
return func(t *testing.T, diff computed.Diff) {
validateDiff(t, diff, action, replace)
_, ok := diff.Renderer.(*writeOnlyRenderer)
if !ok {
t.Errorf("invalid renderer type: %T", diff.Renderer)
return
}
}
}
func ValidateObject(attributes map[string]ValidateDiffFunction, action plans.Action, replace bool) ValidateDiffFunction {
return func(t *testing.T, diff computed.Diff) {
validateDiff(t, diff, action, replace)
@@ -121,6 +135,12 @@ func validateKeys[C, V any](t *testing.T, actual map[string]C, expected map[stri
if diff := cmp.Diff(actualAttributes, expectedAttributes); len(diff) > 0 {
t.Errorf("actual and expected attributes did not match: %s", diff)
}
} else {
gotKeys := slices.Sorted(maps.Keys(actual))
wantKeys := slices.Sorted(maps.Keys(expected))
if diff := cmp.Diff(wantKeys, gotKeys); len(diff) > 0 {
t.Errorf("keys not match: %s", diff)
}
}
}

View File

@@ -0,0 +1,24 @@
// Copyright (c) The OpenTofu Authors
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package renderers
import (
"fmt"
"github.com/opentofu/opentofu/internal/command/jsonformat/computed"
)
func WriteOnly() computed.DiffRenderer {
return &writeOnlyRenderer{}
}
type writeOnlyRenderer struct {
NoWarningsRenderer
}
func (renderer writeOnlyRenderer) RenderHuman(diff computed.Diff, _ int, opts computed.RenderHumanOpts) string {
return fmt.Sprintf("(write-only attribute)%s%s", forcesReplacement(diff.Replace, opts), nullSuffix(diff.Action, opts))
}