mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Make required JSON structured output structures public for processing (#32367)
* prep for processing the structured run output * undo unwanted change to a json key
This commit is contained in:
parent
4fc02469e7
commit
b917154a97
@ -35,9 +35,9 @@ type plan struct {
|
||||
PlannedValues stateValues `json:"planned_values,omitempty"`
|
||||
// ResourceDrift and ResourceChanges are sorted in a user-friendly order
|
||||
// that is undefined at this time, but consistent.
|
||||
ResourceDrift []resourceChange `json:"resource_drift,omitempty"`
|
||||
ResourceChanges []resourceChange `json:"resource_changes,omitempty"`
|
||||
OutputChanges map[string]change `json:"output_changes,omitempty"`
|
||||
ResourceDrift []ResourceChange `json:"resource_drift,omitempty"`
|
||||
ResourceChanges []ResourceChange `json:"resource_changes,omitempty"`
|
||||
OutputChanges map[string]Change `json:"output_changes,omitempty"`
|
||||
PriorState json.RawMessage `json:"prior_state,omitempty"`
|
||||
Config json.RawMessage `json:"configuration,omitempty"`
|
||||
RelevantAttributes []resourceAttr `json:"relevant_attributes,omitempty"`
|
||||
@ -59,7 +59,7 @@ type resourceAttr struct {
|
||||
}
|
||||
|
||||
// Change is the representation of a proposed change for an object.
|
||||
type change struct {
|
||||
type Change struct {
|
||||
// Actions are the actions that will be taken on the object selected by the
|
||||
// properties below. Valid actions values are:
|
||||
// ["no-op"]
|
||||
@ -265,11 +265,11 @@ func (p *plan) marshalPlanVariables(vars map[string]plans.DynamicValue, decls ma
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *plan) marshalResourceChanges(resources []*plans.ResourceInstanceChangeSrc, schemas *terraform.Schemas) ([]resourceChange, error) {
|
||||
var ret []resourceChange
|
||||
func (p *plan) marshalResourceChanges(resources []*plans.ResourceInstanceChangeSrc, schemas *terraform.Schemas) ([]ResourceChange, error) {
|
||||
var ret []ResourceChange
|
||||
|
||||
for _, rc := range resources {
|
||||
var r resourceChange
|
||||
var r ResourceChange
|
||||
addr := rc.Addr
|
||||
r.Address = addr.String()
|
||||
if !addr.Equal(rc.PrevRunAddr) {
|
||||
@ -360,7 +360,7 @@ func (p *plan) marshalResourceChanges(resources []*plans.ResourceInstanceChangeS
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r.Change = change{
|
||||
r.Change = Change{
|
||||
Actions: actionString(rc.Action.String()),
|
||||
Before: json.RawMessage(before),
|
||||
After: json.RawMessage(after),
|
||||
@ -376,7 +376,10 @@ func (p *plan) marshalResourceChanges(resources []*plans.ResourceInstanceChangeS
|
||||
|
||||
key := addr.Resource.Key
|
||||
if key != nil {
|
||||
r.Index = key
|
||||
value := key.Value()
|
||||
if r.Index, err = ctyjson.Marshal(value, value.Type()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
switch addr.Resource.Resource.Mode {
|
||||
@ -440,7 +443,7 @@ func (p *plan) marshalOutputChanges(changes *plans.Changes) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
p.OutputChanges = make(map[string]change, len(changes.Outputs))
|
||||
p.OutputChanges = make(map[string]Change, len(changes.Outputs))
|
||||
for _, oc := range changes.Outputs {
|
||||
changeV, err := oc.Decode()
|
||||
if err != nil {
|
||||
@ -496,7 +499,7 @@ func (p *plan) marshalOutputChanges(changes *plans.Changes) error {
|
||||
|
||||
a, _ := ctyjson.Marshal(afterUnknown, afterUnknown.Type())
|
||||
|
||||
c := change{
|
||||
c := Change{
|
||||
Actions: actionString(oc.Action.String()),
|
||||
Before: json.RawMessage(before),
|
||||
After: json.RawMessage(after),
|
||||
|
@ -41,10 +41,10 @@ type resource struct {
|
||||
SensitiveValues json.RawMessage `json:"sensitive_values,omitempty"`
|
||||
}
|
||||
|
||||
// resourceChange is a description of an individual change action that Terraform
|
||||
// ResourceChange is a description of an individual change action that Terraform
|
||||
// plans to use to move from the prior state to a new state matching the
|
||||
// configuration.
|
||||
type resourceChange struct {
|
||||
type ResourceChange struct {
|
||||
// Address is the absolute resource address
|
||||
Address string `json:"address,omitempty"`
|
||||
|
||||
@ -67,10 +67,10 @@ type resourceChange struct {
|
||||
// "managed" or "data"
|
||||
Mode string `json:"mode,omitempty"`
|
||||
|
||||
Type string `json:"type,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Index addrs.InstanceKey `json:"index,omitempty"`
|
||||
ProviderName string `json:"provider_name,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Index json.RawMessage `json:"index,omitempty"`
|
||||
ProviderName string `json:"provider_name,omitempty"`
|
||||
|
||||
// "deposed", if set, indicates that this action applies to a "deposed"
|
||||
// object of the given instance rather than to its "current" object. Omitted
|
||||
@ -78,7 +78,7 @@ type resourceChange struct {
|
||||
Deposed string `json:"deposed,omitempty"`
|
||||
|
||||
// Change describes the change that will be made to this object
|
||||
Change change `json:"change,omitempty"`
|
||||
Change Change `json:"change,omitempty"`
|
||||
|
||||
// ActionReason is a keyword representing some optional extra context
|
||||
// for why the actions in Change.Actions were chosen.
|
||||
|
@ -7,9 +7,9 @@ import (
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
type attribute struct {
|
||||
type Attribute struct {
|
||||
AttributeType json.RawMessage `json:"type,omitempty"`
|
||||
AttributeNestedType *nestedType `json:"nested_type,omitempty"`
|
||||
AttributeNestedType *NestedType `json:"nested_type,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
DescriptionKind string `json:"description_kind,omitempty"`
|
||||
Deprecated bool `json:"deprecated,omitempty"`
|
||||
@ -19,8 +19,8 @@ type attribute struct {
|
||||
Sensitive bool `json:"sensitive,omitempty"`
|
||||
}
|
||||
|
||||
type nestedType struct {
|
||||
Attributes map[string]*attribute `json:"attributes,omitempty"`
|
||||
type NestedType struct {
|
||||
Attributes map[string]*Attribute `json:"attributes,omitempty"`
|
||||
NestingMode string `json:"nesting_mode,omitempty"`
|
||||
}
|
||||
|
||||
@ -33,8 +33,8 @@ func marshalStringKind(sk configschema.StringKind) string {
|
||||
}
|
||||
}
|
||||
|
||||
func marshalAttribute(attr *configschema.Attribute) *attribute {
|
||||
ret := &attribute{
|
||||
func marshalAttribute(attr *configschema.Attribute) *Attribute {
|
||||
ret := &Attribute{
|
||||
Description: attr.Description,
|
||||
DescriptionKind: marshalStringKind(attr.DescriptionKind),
|
||||
Required: attr.Required,
|
||||
@ -52,10 +52,10 @@ func marshalAttribute(attr *configschema.Attribute) *attribute {
|
||||
}
|
||||
|
||||
if attr.NestedType != nil {
|
||||
nestedTy := nestedType{
|
||||
nestedTy := NestedType{
|
||||
NestingMode: nestingModeString(attr.NestedType.Nesting),
|
||||
}
|
||||
attrs := make(map[string]*attribute, len(attr.NestedType.Attributes))
|
||||
attrs := make(map[string]*Attribute, len(attr.NestedType.Attributes))
|
||||
for k, attr := range attr.NestedType.Attributes {
|
||||
attrs[k] = marshalAttribute(attr)
|
||||
}
|
||||
|
@ -13,11 +13,11 @@ import (
|
||||
func TestMarshalAttribute(t *testing.T) {
|
||||
tests := []struct {
|
||||
Input *configschema.Attribute
|
||||
Want *attribute
|
||||
Want *Attribute
|
||||
}{
|
||||
{
|
||||
&configschema.Attribute{Type: cty.String, Optional: true, Computed: true},
|
||||
&attribute{
|
||||
&Attribute{
|
||||
AttributeType: json.RawMessage(`"string"`),
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
@ -26,7 +26,7 @@ func TestMarshalAttribute(t *testing.T) {
|
||||
},
|
||||
{ // collection types look a little odd.
|
||||
&configschema.Attribute{Type: cty.Map(cty.String), Optional: true, Computed: true},
|
||||
&attribute{
|
||||
&Attribute{
|
||||
AttributeType: json.RawMessage(`["map","string"]`),
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
|
@ -4,26 +4,26 @@ import (
|
||||
"github.com/hashicorp/terraform/internal/configs/configschema"
|
||||
)
|
||||
|
||||
type block struct {
|
||||
Attributes map[string]*attribute `json:"attributes,omitempty"`
|
||||
BlockTypes map[string]*blockType `json:"block_types,omitempty"`
|
||||
type Block struct {
|
||||
Attributes map[string]*Attribute `json:"attributes,omitempty"`
|
||||
BlockTypes map[string]*BlockType `json:"block_types,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
DescriptionKind string `json:"description_kind,omitempty"`
|
||||
Deprecated bool `json:"deprecated,omitempty"`
|
||||
}
|
||||
|
||||
type blockType struct {
|
||||
type BlockType struct {
|
||||
NestingMode string `json:"nesting_mode,omitempty"`
|
||||
Block *block `json:"block,omitempty"`
|
||||
Block *Block `json:"block,omitempty"`
|
||||
MinItems uint64 `json:"min_items,omitempty"`
|
||||
MaxItems uint64 `json:"max_items,omitempty"`
|
||||
}
|
||||
|
||||
func marshalBlockTypes(nestedBlock *configschema.NestedBlock) *blockType {
|
||||
func marshalBlockTypes(nestedBlock *configschema.NestedBlock) *BlockType {
|
||||
if nestedBlock == nil {
|
||||
return &blockType{}
|
||||
return &BlockType{}
|
||||
}
|
||||
ret := &blockType{
|
||||
ret := &BlockType{
|
||||
Block: marshalBlock(&nestedBlock.Block),
|
||||
MinItems: uint64(nestedBlock.MinItems),
|
||||
MaxItems: uint64(nestedBlock.MaxItems),
|
||||
@ -32,19 +32,19 @@ func marshalBlockTypes(nestedBlock *configschema.NestedBlock) *blockType {
|
||||
return ret
|
||||
}
|
||||
|
||||
func marshalBlock(configBlock *configschema.Block) *block {
|
||||
func marshalBlock(configBlock *configschema.Block) *Block {
|
||||
if configBlock == nil {
|
||||
return &block{}
|
||||
return &Block{}
|
||||
}
|
||||
|
||||
ret := block{
|
||||
ret := Block{
|
||||
Deprecated: configBlock.Deprecated,
|
||||
Description: configBlock.Description,
|
||||
DescriptionKind: marshalStringKind(configBlock.DescriptionKind),
|
||||
}
|
||||
|
||||
if len(configBlock.Attributes) > 0 {
|
||||
attrs := make(map[string]*attribute, len(configBlock.Attributes))
|
||||
attrs := make(map[string]*Attribute, len(configBlock.Attributes))
|
||||
for k, attr := range configBlock.Attributes {
|
||||
attrs[k] = marshalAttribute(attr)
|
||||
}
|
||||
@ -52,7 +52,7 @@ func marshalBlock(configBlock *configschema.Block) *block {
|
||||
}
|
||||
|
||||
if len(configBlock.BlockTypes) > 0 {
|
||||
blockTypes := make(map[string]*blockType, len(configBlock.BlockTypes))
|
||||
blockTypes := make(map[string]*BlockType, len(configBlock.BlockTypes))
|
||||
for k, bt := range configBlock.BlockTypes {
|
||||
blockTypes[k] = marshalBlockTypes(bt)
|
||||
}
|
||||
|
@ -13,11 +13,11 @@ import (
|
||||
func TestMarshalBlock(t *testing.T) {
|
||||
tests := []struct {
|
||||
Input *configschema.Block
|
||||
Want *block
|
||||
Want *Block
|
||||
}{
|
||||
{
|
||||
nil,
|
||||
&block{},
|
||||
&Block{},
|
||||
},
|
||||
{
|
||||
Input: &configschema.Block{
|
||||
@ -37,16 +37,16 @@ func TestMarshalBlock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
Want: &block{
|
||||
Attributes: map[string]*attribute{
|
||||
Want: &Block{
|
||||
Attributes: map[string]*Attribute{
|
||||
"ami": {AttributeType: json.RawMessage(`"string"`), Optional: true, DescriptionKind: "plain"},
|
||||
"id": {AttributeType: json.RawMessage(`"string"`), Optional: true, Computed: true, DescriptionKind: "plain"},
|
||||
},
|
||||
BlockTypes: map[string]*blockType{
|
||||
BlockTypes: map[string]*BlockType{
|
||||
"network_interface": {
|
||||
NestingMode: "list",
|
||||
Block: &block{
|
||||
Attributes: map[string]*attribute{
|
||||
Block: &Block{
|
||||
Attributes: map[string]*Attribute{
|
||||
"description": {AttributeType: json.RawMessage(`"string"`), Optional: true, DescriptionKind: "plain"},
|
||||
"device_index": {AttributeType: json.RawMessage(`"string"`), Optional: true, DescriptionKind: "plain"},
|
||||
},
|
||||
|
@ -18,9 +18,9 @@ type providers struct {
|
||||
}
|
||||
|
||||
type Provider struct {
|
||||
Provider *schema `json:"provider,omitempty"`
|
||||
ResourceSchemas map[string]*schema `json:"resource_schemas,omitempty"`
|
||||
DataSourceSchemas map[string]*schema `json:"data_source_schemas,omitempty"`
|
||||
Provider *Schema `json:"provider,omitempty"`
|
||||
ResourceSchemas map[string]*Schema `json:"resource_schemas,omitempty"`
|
||||
DataSourceSchemas map[string]*Schema `json:"data_source_schemas,omitempty"`
|
||||
}
|
||||
|
||||
func newProviders() *providers {
|
||||
@ -47,8 +47,8 @@ func marshalProvider(tps *terraform.ProviderSchema) *Provider {
|
||||
return &Provider{}
|
||||
}
|
||||
|
||||
var ps *schema
|
||||
var rs, ds map[string]*schema
|
||||
var ps *Schema
|
||||
var rs, ds map[string]*Schema
|
||||
|
||||
if tps.Provider != nil {
|
||||
ps = marshalSchema(tps.Provider)
|
||||
|
@ -23,9 +23,9 @@ func TestMarshalProvider(t *testing.T) {
|
||||
{
|
||||
testProvider(),
|
||||
&Provider{
|
||||
Provider: &schema{
|
||||
Block: &block{
|
||||
Attributes: map[string]*attribute{
|
||||
Provider: &Schema{
|
||||
Block: &Block{
|
||||
Attributes: map[string]*Attribute{
|
||||
"region": {
|
||||
AttributeType: json.RawMessage(`"string"`),
|
||||
Required: true,
|
||||
@ -35,11 +35,11 @@ func TestMarshalProvider(t *testing.T) {
|
||||
DescriptionKind: "plain",
|
||||
},
|
||||
},
|
||||
ResourceSchemas: map[string]*schema{
|
||||
ResourceSchemas: map[string]*Schema{
|
||||
"test_instance": {
|
||||
Version: 42,
|
||||
Block: &block{
|
||||
Attributes: map[string]*attribute{
|
||||
Block: &Block{
|
||||
Attributes: map[string]*Attribute{
|
||||
"id": {
|
||||
AttributeType: json.RawMessage(`"string"`),
|
||||
Optional: true,
|
||||
@ -52,9 +52,9 @@ func TestMarshalProvider(t *testing.T) {
|
||||
DescriptionKind: "plain",
|
||||
},
|
||||
"volumes": {
|
||||
AttributeNestedType: &nestedType{
|
||||
AttributeNestedType: &NestedType{
|
||||
NestingMode: "list",
|
||||
Attributes: map[string]*attribute{
|
||||
Attributes: map[string]*Attribute{
|
||||
"size": {
|
||||
AttributeType: json.RawMessage(`"string"`),
|
||||
Required: true,
|
||||
@ -71,10 +71,10 @@ func TestMarshalProvider(t *testing.T) {
|
||||
DescriptionKind: "plain",
|
||||
},
|
||||
},
|
||||
BlockTypes: map[string]*blockType{
|
||||
BlockTypes: map[string]*BlockType{
|
||||
"network_interface": {
|
||||
Block: &block{
|
||||
Attributes: map[string]*attribute{
|
||||
Block: &Block{
|
||||
Attributes: map[string]*Attribute{
|
||||
"device_index": {
|
||||
AttributeType: json.RawMessage(`"string"`),
|
||||
Optional: true,
|
||||
@ -95,11 +95,11 @@ func TestMarshalProvider(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
DataSourceSchemas: map[string]*schema{
|
||||
DataSourceSchemas: map[string]*Schema{
|
||||
"test_data_source": {
|
||||
Version: 3,
|
||||
Block: &block{
|
||||
Attributes: map[string]*attribute{
|
||||
Block: &Block{
|
||||
Attributes: map[string]*Attribute{
|
||||
"id": {
|
||||
AttributeType: json.RawMessage(`"string"`),
|
||||
Optional: true,
|
||||
@ -112,10 +112,10 @@ func TestMarshalProvider(t *testing.T) {
|
||||
DescriptionKind: "plain",
|
||||
},
|
||||
},
|
||||
BlockTypes: map[string]*blockType{
|
||||
BlockTypes: map[string]*BlockType{
|
||||
"network_interface": {
|
||||
Block: &block{
|
||||
Attributes: map[string]*attribute{
|
||||
Block: &Block{
|
||||
Attributes: map[string]*Attribute{
|
||||
"device_index": {
|
||||
AttributeType: json.RawMessage(`"string"`),
|
||||
Optional: true,
|
||||
|
@ -4,29 +4,29 @@ import (
|
||||
"github.com/hashicorp/terraform/internal/configs/configschema"
|
||||
)
|
||||
|
||||
type schema struct {
|
||||
type Schema struct {
|
||||
Version uint64 `json:"version"`
|
||||
Block *block `json:"block,omitempty"`
|
||||
Block *Block `json:"block,omitempty"`
|
||||
}
|
||||
|
||||
// marshalSchema is a convenience wrapper around mashalBlock. Schema version
|
||||
// should be set by the caller.
|
||||
func marshalSchema(block *configschema.Block) *schema {
|
||||
func marshalSchema(block *configschema.Block) *Schema {
|
||||
if block == nil {
|
||||
return &schema{}
|
||||
return &Schema{}
|
||||
}
|
||||
|
||||
var ret schema
|
||||
var ret Schema
|
||||
ret.Block = marshalBlock(block)
|
||||
|
||||
return &ret
|
||||
}
|
||||
|
||||
func marshalSchemas(blocks map[string]*configschema.Block, rVersions map[string]uint64) map[string]*schema {
|
||||
func marshalSchemas(blocks map[string]*configschema.Block, rVersions map[string]uint64) map[string]*Schema {
|
||||
if blocks == nil {
|
||||
return map[string]*schema{}
|
||||
return map[string]*Schema{}
|
||||
}
|
||||
ret := make(map[string]*schema, len(blocks))
|
||||
ret := make(map[string]*Schema, len(blocks))
|
||||
for k, v := range blocks {
|
||||
ret[k] = marshalSchema(v)
|
||||
version, ok := rVersions[k]
|
||||
|
@ -12,12 +12,12 @@ func TestMarshalSchemas(t *testing.T) {
|
||||
tests := []struct {
|
||||
Input map[string]*configschema.Block
|
||||
Versions map[string]uint64
|
||||
Want map[string]*schema
|
||||
Want map[string]*Schema
|
||||
}{
|
||||
{
|
||||
nil,
|
||||
map[string]uint64{},
|
||||
map[string]*schema{},
|
||||
map[string]*Schema{},
|
||||
},
|
||||
}
|
||||
|
||||
@ -32,11 +32,11 @@ func TestMarshalSchemas(t *testing.T) {
|
||||
func TestMarshalSchema(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
Input *configschema.Block
|
||||
Want *schema
|
||||
Want *Schema
|
||||
}{
|
||||
"nil_block": {
|
||||
nil,
|
||||
&schema{},
|
||||
&Schema{},
|
||||
},
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user