Merge pull request #27885 from hashicorp/jbardin/show-json
jsonstate: indicate schema version mismatch during encoding
This commit is contained in:
commit
c103242bef
|
@ -300,7 +300,7 @@ func marshalResources(resources map[string]*states.Resource, module addrs.Module
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
schema, _ := schemas.ResourceTypeConfig(
|
schema, version := schemas.ResourceTypeConfig(
|
||||||
r.ProviderConfig.Provider,
|
r.ProviderConfig.Provider,
|
||||||
resAddr.Mode,
|
resAddr.Mode,
|
||||||
resAddr.Type,
|
resAddr.Type,
|
||||||
|
@ -308,6 +308,10 @@ func marshalResources(resources map[string]*states.Resource, module addrs.Module
|
||||||
|
|
||||||
// It is possible that the only instance is deposed
|
// It is possible that the only instance is deposed
|
||||||
if ri.Current != nil {
|
if ri.Current != nil {
|
||||||
|
if version != ri.Current.SchemaVersion {
|
||||||
|
return nil, fmt.Errorf("schema version %d for %s in state does not match version %d from the provider", ri.Current.SchemaVersion, resAddr, version)
|
||||||
|
}
|
||||||
|
|
||||||
current.SchemaVersion = ri.Current.SchemaVersion
|
current.SchemaVersion = ri.Current.SchemaVersion
|
||||||
|
|
||||||
if schema == nil {
|
if schema == nil {
|
||||||
|
|
|
@ -167,7 +167,6 @@ func TestMarshalResources(t *testing.T) {
|
||||||
Instances: map[addrs.InstanceKey]*states.ResourceInstance{
|
Instances: map[addrs.InstanceKey]*states.ResourceInstance{
|
||||||
addrs.NoKey: {
|
addrs.NoKey: {
|
||||||
Current: &states.ResourceInstanceObjectSrc{
|
Current: &states.ResourceInstanceObjectSrc{
|
||||||
SchemaVersion: 1,
|
|
||||||
Status: states.ObjectReady,
|
Status: states.ObjectReady,
|
||||||
AttrsJSON: []byte(`{"woozles":"confuzles"}`),
|
AttrsJSON: []byte(`{"woozles":"confuzles"}`),
|
||||||
},
|
},
|
||||||
|
@ -188,7 +187,6 @@ func TestMarshalResources(t *testing.T) {
|
||||||
Name: "bar",
|
Name: "bar",
|
||||||
Index: addrs.InstanceKey(nil),
|
Index: addrs.InstanceKey(nil),
|
||||||
ProviderName: "registry.terraform.io/hashicorp/test",
|
ProviderName: "registry.terraform.io/hashicorp/test",
|
||||||
SchemaVersion: 1,
|
|
||||||
AttributeValues: attributeValues{
|
AttributeValues: attributeValues{
|
||||||
"foozles": json.RawMessage(`null`),
|
"foozles": json.RawMessage(`null`),
|
||||||
"woozles": json.RawMessage(`"confuzles"`),
|
"woozles": json.RawMessage(`"confuzles"`),
|
||||||
|
@ -197,6 +195,35 @@ func TestMarshalResources(t *testing.T) {
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
"single resource wrong schema": {
|
||||||
|
map[string]*states.Resource{
|
||||||
|
"test_thing.baz": {
|
||||||
|
Addr: addrs.AbsResource{
|
||||||
|
Resource: addrs.Resource{
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Type: "test_thing",
|
||||||
|
Name: "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Instances: map[addrs.InstanceKey]*states.ResourceInstance{
|
||||||
|
addrs.NoKey: {
|
||||||
|
Current: &states.ResourceInstanceObjectSrc{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
Status: states.ObjectReady,
|
||||||
|
AttrsJSON: []byte(`{"woozles":["confuzles"]}`),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ProviderConfig: addrs.AbsProviderConfig{
|
||||||
|
Provider: addrs.NewDefaultProvider("test"),
|
||||||
|
Module: addrs.RootModule,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
testSchemas(),
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
"resource with count": {
|
"resource with count": {
|
||||||
map[string]*states.Resource{
|
map[string]*states.Resource{
|
||||||
"test_thing.bar": {
|
"test_thing.bar": {
|
||||||
|
@ -210,7 +237,6 @@ func TestMarshalResources(t *testing.T) {
|
||||||
Instances: map[addrs.InstanceKey]*states.ResourceInstance{
|
Instances: map[addrs.InstanceKey]*states.ResourceInstance{
|
||||||
addrs.IntKey(0): {
|
addrs.IntKey(0): {
|
||||||
Current: &states.ResourceInstanceObjectSrc{
|
Current: &states.ResourceInstanceObjectSrc{
|
||||||
SchemaVersion: 1,
|
|
||||||
Status: states.ObjectReady,
|
Status: states.ObjectReady,
|
||||||
AttrsJSON: []byte(`{"woozles":"confuzles"}`),
|
AttrsJSON: []byte(`{"woozles":"confuzles"}`),
|
||||||
},
|
},
|
||||||
|
@ -231,7 +257,6 @@ func TestMarshalResources(t *testing.T) {
|
||||||
Name: "bar",
|
Name: "bar",
|
||||||
Index: addrs.IntKey(0),
|
Index: addrs.IntKey(0),
|
||||||
ProviderName: "registry.terraform.io/hashicorp/test",
|
ProviderName: "registry.terraform.io/hashicorp/test",
|
||||||
SchemaVersion: 1,
|
|
||||||
AttributeValues: attributeValues{
|
AttributeValues: attributeValues{
|
||||||
"foozles": json.RawMessage(`null`),
|
"foozles": json.RawMessage(`null`),
|
||||||
"woozles": json.RawMessage(`"confuzles"`),
|
"woozles": json.RawMessage(`"confuzles"`),
|
||||||
|
@ -253,7 +278,6 @@ func TestMarshalResources(t *testing.T) {
|
||||||
Instances: map[addrs.InstanceKey]*states.ResourceInstance{
|
Instances: map[addrs.InstanceKey]*states.ResourceInstance{
|
||||||
addrs.StringKey("rockhopper"): {
|
addrs.StringKey("rockhopper"): {
|
||||||
Current: &states.ResourceInstanceObjectSrc{
|
Current: &states.ResourceInstanceObjectSrc{
|
||||||
SchemaVersion: 1,
|
|
||||||
Status: states.ObjectReady,
|
Status: states.ObjectReady,
|
||||||
AttrsJSON: []byte(`{"woozles":"confuzles"}`),
|
AttrsJSON: []byte(`{"woozles":"confuzles"}`),
|
||||||
},
|
},
|
||||||
|
@ -274,7 +298,6 @@ func TestMarshalResources(t *testing.T) {
|
||||||
Name: "bar",
|
Name: "bar",
|
||||||
Index: addrs.StringKey("rockhopper"),
|
Index: addrs.StringKey("rockhopper"),
|
||||||
ProviderName: "registry.terraform.io/hashicorp/test",
|
ProviderName: "registry.terraform.io/hashicorp/test",
|
||||||
SchemaVersion: 1,
|
|
||||||
AttributeValues: attributeValues{
|
AttributeValues: attributeValues{
|
||||||
"foozles": json.RawMessage(`null`),
|
"foozles": json.RawMessage(`null`),
|
||||||
"woozles": json.RawMessage(`"confuzles"`),
|
"woozles": json.RawMessage(`"confuzles"`),
|
||||||
|
@ -297,7 +320,6 @@ func TestMarshalResources(t *testing.T) {
|
||||||
addrs.NoKey: {
|
addrs.NoKey: {
|
||||||
Deposed: map[states.DeposedKey]*states.ResourceInstanceObjectSrc{
|
Deposed: map[states.DeposedKey]*states.ResourceInstanceObjectSrc{
|
||||||
states.DeposedKey(deposedKey): &states.ResourceInstanceObjectSrc{
|
states.DeposedKey(deposedKey): &states.ResourceInstanceObjectSrc{
|
||||||
SchemaVersion: 1,
|
|
||||||
Status: states.ObjectReady,
|
Status: states.ObjectReady,
|
||||||
AttrsJSON: []byte(`{"woozles":"confuzles"}`),
|
AttrsJSON: []byte(`{"woozles":"confuzles"}`),
|
||||||
},
|
},
|
||||||
|
@ -342,13 +364,11 @@ func TestMarshalResources(t *testing.T) {
|
||||||
addrs.NoKey: {
|
addrs.NoKey: {
|
||||||
Deposed: map[states.DeposedKey]*states.ResourceInstanceObjectSrc{
|
Deposed: map[states.DeposedKey]*states.ResourceInstanceObjectSrc{
|
||||||
states.DeposedKey(deposedKey): &states.ResourceInstanceObjectSrc{
|
states.DeposedKey(deposedKey): &states.ResourceInstanceObjectSrc{
|
||||||
SchemaVersion: 1,
|
|
||||||
Status: states.ObjectReady,
|
Status: states.ObjectReady,
|
||||||
AttrsJSON: []byte(`{"woozles":"confuzles"}`),
|
AttrsJSON: []byte(`{"woozles":"confuzles"}`),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Current: &states.ResourceInstanceObjectSrc{
|
Current: &states.ResourceInstanceObjectSrc{
|
||||||
SchemaVersion: 1,
|
|
||||||
Status: states.ObjectReady,
|
Status: states.ObjectReady,
|
||||||
AttrsJSON: []byte(`{"woozles":"confuzles"}`),
|
AttrsJSON: []byte(`{"woozles":"confuzles"}`),
|
||||||
},
|
},
|
||||||
|
@ -369,7 +389,6 @@ func TestMarshalResources(t *testing.T) {
|
||||||
Name: "bar",
|
Name: "bar",
|
||||||
Index: addrs.InstanceKey(nil),
|
Index: addrs.InstanceKey(nil),
|
||||||
ProviderName: "registry.terraform.io/hashicorp/test",
|
ProviderName: "registry.terraform.io/hashicorp/test",
|
||||||
SchemaVersion: 1,
|
|
||||||
AttributeValues: attributeValues{
|
AttributeValues: attributeValues{
|
||||||
"foozles": json.RawMessage(`null`),
|
"foozles": json.RawMessage(`null`),
|
||||||
"woozles": json.RawMessage(`"confuzles"`),
|
"woozles": json.RawMessage(`"confuzles"`),
|
||||||
|
|
|
@ -28,6 +28,12 @@ For Terraform state files (including when no path is provided),
|
||||||
For Terraform plan files, `terraform show -json` will show a JSON representation
|
For Terraform plan files, `terraform show -json` will show a JSON representation
|
||||||
of the plan, configuration, and current state.
|
of the plan, configuration, and current state.
|
||||||
|
|
||||||
|
If you've updated providers which contain new schema versions since the state
|
||||||
|
was written, the state needs to be upgraded before it can be displayed with
|
||||||
|
`show -json`. If you are viewing a plan, it must be created without
|
||||||
|
`-refresh=false`. If you are viewing a state file, run `terraform refresh`
|
||||||
|
first.
|
||||||
|
|
||||||
The output format is covered in detail in [JSON Output Format](/docs/internals/json-format.html).
|
The output format is covered in detail in [JSON Output Format](/docs/internals/json-format.html).
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
Loading…
Reference in New Issue