mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Structured Plan Renderer: Read the data source schemas from the right place (#32532)
* read the data source schemas from the right place * address comments and add test
This commit is contained in:
parent
7a019fa767
commit
6dc49150b7
@ -43,7 +43,7 @@ func precomputeDiffs(plan Plan, mode plans.Mode) diffs {
|
||||
continue
|
||||
}
|
||||
|
||||
schema := plan.ProviderSchemas[drift.ProviderName].ResourceSchemas[drift.Type]
|
||||
schema := plan.GetSchema(drift)
|
||||
diffs.drift = append(diffs.drift, diff{
|
||||
change: drift,
|
||||
diff: differ.FromJsonChange(drift.Change, relevantAttrs).ComputeDiffForBlock(schema.Block),
|
||||
@ -51,7 +51,7 @@ func precomputeDiffs(plan Plan, mode plans.Mode) diffs {
|
||||
}
|
||||
|
||||
for _, change := range plan.ResourceChanges {
|
||||
schema := plan.ProviderSchemas[change.ProviderName].ResourceSchemas[change.Type]
|
||||
schema := plan.GetSchema(change)
|
||||
diffs.changes = append(diffs.changes, diff{
|
||||
change: change,
|
||||
diff: differ.FromJsonChange(change.Change, attribute_path.AlwaysMatcher()).ComputeDiffForBlock(schema.Block),
|
||||
|
@ -39,6 +39,17 @@ type Plan struct {
|
||||
ProviderSchemas map[string]*jsonprovider.Provider `json:"provider_schemas"`
|
||||
}
|
||||
|
||||
func (plan Plan) GetSchema(change jsonplan.ResourceChange) *jsonprovider.Schema {
|
||||
switch change.Mode {
|
||||
case jsonplan.ManagedResourceMode:
|
||||
return plan.ProviderSchemas[change.ProviderName].ResourceSchemas[change.Type]
|
||||
case jsonplan.DataResourceMode:
|
||||
return plan.ProviderSchemas[change.ProviderName].DataSourceSchemas[change.Type]
|
||||
default:
|
||||
panic("found unrecognized resource mode: " + change.Mode)
|
||||
}
|
||||
}
|
||||
|
||||
type Renderer struct {
|
||||
Streams *terminal.Streams
|
||||
Colorize *colorstring.Colorize
|
||||
@ -78,7 +89,7 @@ func (r Renderer) RenderHumanPlan(plan Plan, mode plans.Mode, opts ...RendererOp
|
||||
// Don't show anything for NoOp changes.
|
||||
continue
|
||||
}
|
||||
if action == plans.Delete && diff.change.Mode != "managed" {
|
||||
if action == plans.Delete && diff.change.Mode != jsonplan.ManagedResourceMode {
|
||||
// Don't render anything for deleted data sources.
|
||||
continue
|
||||
}
|
||||
@ -464,7 +475,7 @@ func resourceChangeComment(resource jsonplan.ResourceChange, action plans.Action
|
||||
|
||||
func resourceChangeHeader(change jsonplan.ResourceChange) string {
|
||||
mode := "resource"
|
||||
if change.Mode != "managed" {
|
||||
if change.Mode != jsonplan.ManagedResourceMode {
|
||||
mode = "data"
|
||||
}
|
||||
return fmt.Sprintf("%s \"%s\" \"%s\"", mode, change.Type, change.Name)
|
||||
|
@ -39,6 +39,9 @@ const (
|
||||
ResourceInstanceDeleteBecauseNoMoveTarget = "delete_because_no_move_target"
|
||||
ResourceInstanceReadBecauseConfigUnknown = "read_because_config_unknown"
|
||||
ResourceInstanceReadBecauseDependencyPending = "read_because_dependency_pending"
|
||||
|
||||
ManagedResourceMode = "managed"
|
||||
DataResourceMode = "data"
|
||||
)
|
||||
|
||||
// Plan is the top-level representation of the json format of a plan. It includes
|
||||
@ -445,9 +448,9 @@ func MarshalResourceChanges(resources []*plans.ResourceInstanceChangeSrc, schema
|
||||
|
||||
switch addr.Resource.Resource.Mode {
|
||||
case addrs.ManagedResourceMode:
|
||||
r.Mode = "managed"
|
||||
r.Mode = ManagedResourceMode
|
||||
case addrs.DataResourceMode:
|
||||
r.Mode = "data"
|
||||
r.Mode = DataResourceMode
|
||||
default:
|
||||
return nil, fmt.Errorf("resource %s has an unsupported mode %s", r.Address, addr.Resource.Resource.Mode.String())
|
||||
}
|
||||
|
@ -356,6 +356,78 @@ Plan: 1 to add, 0 to change, 0 to destroy.
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperation_planWithDatasource(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
v := NewOperation(arguments.ViewHuman, true, NewView(streams))
|
||||
|
||||
plan := testPlanWithDatasource(t)
|
||||
schemas := testSchemas()
|
||||
v.Plan(plan, schemas)
|
||||
|
||||
want := `
|
||||
Terraform used the selected providers to generate the following execution
|
||||
plan. Resource actions are indicated with the following symbols:
|
||||
+ create
|
||||
<= read (data resources)
|
||||
|
||||
Terraform will perform the following actions:
|
||||
|
||||
# data.test_data_source.bar will be read during apply
|
||||
<= data "test_data_source" "bar" {
|
||||
+ bar = "foo"
|
||||
+ id = "C6743020-40BD-4591-81E6-CD08494341D3"
|
||||
}
|
||||
|
||||
# test_resource.foo will be created
|
||||
+ resource "test_resource" "foo" {
|
||||
+ foo = "bar"
|
||||
+ id = (known after apply)
|
||||
}
|
||||
|
||||
Plan: 1 to add, 0 to change, 0 to destroy.
|
||||
`
|
||||
|
||||
if got := done(t).Stdout(); got != want {
|
||||
t.Errorf("unexpected output\ngot:\n%s\nwant:\n%s", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperation_planWithDatasourceAndDrift(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
v := NewOperation(arguments.ViewHuman, true, NewView(streams))
|
||||
|
||||
plan := testPlanWithDatasource(t)
|
||||
schemas := testSchemas()
|
||||
v.Plan(plan, schemas)
|
||||
|
||||
want := `
|
||||
Terraform used the selected providers to generate the following execution
|
||||
plan. Resource actions are indicated with the following symbols:
|
||||
+ create
|
||||
<= read (data resources)
|
||||
|
||||
Terraform will perform the following actions:
|
||||
|
||||
# data.test_data_source.bar will be read during apply
|
||||
<= data "test_data_source" "bar" {
|
||||
+ bar = "foo"
|
||||
+ id = "C6743020-40BD-4591-81E6-CD08494341D3"
|
||||
}
|
||||
|
||||
# test_resource.foo will be created
|
||||
+ resource "test_resource" "foo" {
|
||||
+ foo = "bar"
|
||||
+ id = (known after apply)
|
||||
}
|
||||
|
||||
Plan: 1 to add, 0 to change, 0 to destroy.
|
||||
`
|
||||
|
||||
if got := done(t).Stdout(); got != want {
|
||||
t.Errorf("unexpected output\ngot:\n%s\nwant:\n%s", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperation_planNextStep(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
path string
|
||||
|
@ -88,6 +88,45 @@ func testPlan(t *testing.T) *plans.Plan {
|
||||
}
|
||||
}
|
||||
|
||||
func testPlanWithDatasource(t *testing.T) *plans.Plan {
|
||||
plan := testPlan(t)
|
||||
|
||||
addr := addrs.Resource{
|
||||
Mode: addrs.DataResourceMode,
|
||||
Type: "test_data_source",
|
||||
Name: "bar",
|
||||
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance)
|
||||
|
||||
dataVal := cty.ObjectVal(map[string]cty.Value{
|
||||
"id": cty.StringVal("C6743020-40BD-4591-81E6-CD08494341D3"),
|
||||
"bar": cty.StringVal("foo"),
|
||||
})
|
||||
priorValRaw, err := plans.NewDynamicValue(cty.NullVal(dataVal.Type()), dataVal.Type())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
plannedValRaw, err := plans.NewDynamicValue(dataVal, dataVal.Type())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
plan.Changes.SyncWrapper().AppendResourceInstanceChange(&plans.ResourceInstanceChangeSrc{
|
||||
Addr: addr,
|
||||
PrevRunAddr: addr,
|
||||
ProviderAddr: addrs.AbsProviderConfig{
|
||||
Provider: addrs.NewDefaultProvider("test"),
|
||||
Module: addrs.RootModule,
|
||||
},
|
||||
ChangeSrc: plans.ChangeSrc{
|
||||
Action: plans.Read,
|
||||
Before: priorValRaw,
|
||||
After: plannedValRaw,
|
||||
},
|
||||
})
|
||||
|
||||
return plan
|
||||
}
|
||||
|
||||
func testSchemas() *terraform.Schemas {
|
||||
provider := testProvider()
|
||||
return &terraform.Schemas{
|
||||
@ -123,5 +162,15 @@ func testProviderSchema() *providers.GetProviderSchemaResponse {
|
||||
},
|
||||
},
|
||||
},
|
||||
DataSources: map[string]providers.Schema{
|
||||
"test_data_source": {
|
||||
Block: &configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"id": {Type: cty.String, Required: true},
|
||||
"bar": {Type: cty.String, Optional: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user