2016-05-08 01:41:27 -05:00
package terraform
import (
"fmt"
2018-10-02 12:58:49 -05:00
"log"
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
"github.com/zclconf/go-cty/cty"
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs"
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
"github.com/hashicorp/terraform/plans"
2018-08-28 16:55:28 -05:00
"github.com/hashicorp/terraform/plans/objchange"
"github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/states"
"github.com/hashicorp/terraform/tfdiags"
2016-05-08 01:41:27 -05:00
)
2018-10-02 12:58:49 -05:00
// EvalReadData is an EvalNode implementation that deals with the main part
// of the data resource lifecycle: either actually reading from the data source
// or generating a plan to do so.
type EvalReadData struct {
Addr addrs . ResourceInstance
Config * configs . Resource
Provider * providers . Interface
ProviderAddr addrs . AbsProviderConfig
ProviderSchema * * ProviderSchema
// Planned is set when dealing with data resources that were deferred to
// the apply walk, to let us see what was planned. If this is set, the
// evaluation of the config is required to produce a wholly-known
// configuration which is consistent with the partial object included
// in this planned change.
Planned * * plans . ResourceInstanceChange
2018-10-02 17:47:37 -05:00
// ForcePlanRead, if true, overrides the usual behavior of immediately
// reading from the data source where possible, instead forcing us to
// _always_ generate a plan. This is used during the plan walk, since we
// mustn't actually apply anything there. (The resulting state doesn't
// get persisted)
ForcePlanRead bool
2018-10-02 12:58:49 -05:00
// The result from this EvalNode has a few different possibilities
// depending on the input:
// - If Planned is nil then we assume we're aiming to _produce_ the plan,
// and so the following two outcomes are possible:
// - OutputChange.Action is plans.NoOp and OutputState is the complete
// result of reading from the data source. This is the easy path.
// - OutputChange.Action is plans.Read and OutputState is a planned
// object placeholder (states.ObjectPlanned). In this case, the
// returned change must be recorded in the overral changeset and
// eventually passed to another instance of this struct during the
// apply walk.
// - If Planned is non-nil then we assume we're aiming to complete a
// planned read from an earlier plan walk. In this case the only possible
// non-error outcome is to set Output.Action (if non-nil) to a plans.NoOp
// change and put the complete resulting state in OutputState, ready to
// be saved in the overall state and used for expression evaluation.
OutputChange * * plans . ResourceInstanceChange
OutputValue * cty . Value
OutputConfigValue * cty . Value
OutputState * * states . ResourceInstanceObject
}
func ( n * EvalReadData ) Eval ( ctx EvalContext ) ( interface { } , error ) {
absAddr := n . Addr . Absolute ( ctx . Path ( ) )
log . Printf ( "[TRACE] EvalReadData: working on %s" , absAddr )
if n . ProviderSchema == nil || * n . ProviderSchema == nil {
return nil , fmt . Errorf ( "provider schema not available for %s" , n . Addr )
}
var diags tfdiags . Diagnostics
var change * plans . ResourceInstanceChange
var configVal cty . Value
// TODO: Do we need to handle Delete changes here? EvalReadDataDiff and
// EvalReadDataApply did, but it seems like we should handle that via a
// separate mechanism since it boils down to just deleting the object from
// the state... and we do that on every plan anyway, forcing the data
// resource to re-read.
config := * n . Config
provider := * n . Provider
providerSchema := * n . ProviderSchema
2018-11-27 17:30:18 -06:00
schema , _ := providerSchema . SchemaForResourceAddr ( n . Addr . ContainingResource ( ) )
2018-10-02 12:58:49 -05:00
if schema == nil {
// Should be caught during validation, so we don't bother with a pretty error here
2020-02-13 14:32:58 -06:00
return nil , fmt . Errorf ( "provider %q does not support data source %q" , n . ProviderAddr . Provider . LegacyString ( ) , n . Addr . Resource . Type )
2018-10-02 12:58:49 -05:00
}
// We'll always start by evaluating the configuration. What we do after
// that will depend on the evaluation result along with what other inputs
// we were given.
objTy := schema . ImpliedType ( )
priorVal := cty . NullVal ( objTy ) // for data resources, prior is always null because we start fresh every time
2019-06-12 10:07:32 -05:00
forEach , _ := evaluateResourceForEachExpression ( n . Config . ForEach , ctx )
keyData := EvalDataForInstanceKey ( n . Addr . Key , forEach )
2018-10-02 12:58:49 -05:00
var configDiags tfdiags . Diagnostics
configVal , _ , configDiags = ctx . EvaluateBlock ( config . Config , schema , nil , keyData )
diags = diags . Append ( configDiags )
if configDiags . HasErrors ( ) {
return nil , diags . Err ( )
}
2019-02-07 20:33:05 -06:00
proposedNewVal := objchange . PlannedDataResourceObject ( schema , configVal )
2018-10-02 12:58:49 -05:00
// If our configuration contains any unknown values then we must defer the
// read to the apply phase by producing a "Read" change for this resource,
// and a placeholder value for it in the state.
2018-10-02 17:47:37 -05:00
if n . ForcePlanRead || ! configVal . IsWhollyKnown ( ) {
2018-10-02 12:58:49 -05:00
// If the configuration is still unknown when we're applying a planned
// change then that indicates a bug in Terraform, since we should have
// everything resolved by now.
if n . Planned != nil && * n . Planned != nil {
return nil , fmt . Errorf (
"configuration for %s still contains unknown values during apply (this is a bug in Terraform; please report it!)" ,
absAddr ,
)
}
2019-02-07 20:33:05 -06:00
if n . ForcePlanRead {
log . Printf ( "[TRACE] EvalReadData: %s configuration is fully known, but we're forcing a read plan to be created" , absAddr )
} else {
log . Printf ( "[TRACE] EvalReadData: %s configuration not fully known yet, so deferring to apply phase" , absAddr )
}
2018-10-02 12:58:49 -05:00
err := ctx . Hook ( func ( h Hook ) ( HookAction , error ) {
return h . PreDiff ( absAddr , states . CurrentGen , priorVal , proposedNewVal )
} )
if err != nil {
return nil , err
}
change = & plans . ResourceInstanceChange {
Addr : absAddr ,
ProviderAddr : n . ProviderAddr ,
Change : plans . Change {
Action : plans . Read ,
Before : priorVal ,
After : proposedNewVal ,
} ,
}
err = ctx . Hook ( func ( h Hook ) ( HookAction , error ) {
return h . PostDiff ( absAddr , states . CurrentGen , change . Action , priorVal , proposedNewVal )
} )
if err != nil {
return nil , err
}
if n . OutputChange != nil {
* n . OutputChange = change
}
if n . OutputValue != nil {
* n . OutputValue = change . After
}
if n . OutputConfigValue != nil {
* n . OutputConfigValue = configVal
}
if n . OutputState != nil {
state := & states . ResourceInstanceObject {
2019-10-17 15:05:27 -05:00
Value : change . After ,
Status : states . ObjectPlanned , // because the partial value in the plan must be used for now
2018-10-02 12:58:49 -05:00
}
* n . OutputState = state
}
return nil , diags . ErrWithWarnings ( )
}
if n . Planned != nil && * n . Planned != nil && ( * n . Planned ) . Action != plans . Read {
// If any other action gets in here then that's always a bug; this
// EvalNode only deals with reading.
return nil , fmt . Errorf (
"invalid action %s for %s: only Read is supported (this is a bug in Terraform; please report it!)" ,
( * n . Planned ) . Action , absAddr ,
)
}
2019-06-01 10:40:54 -05:00
log . Printf ( "[TRACE] Re-validating config for %s" , absAddr )
validateResp := provider . ValidateDataSourceConfig (
providers . ValidateDataSourceConfigRequest {
TypeName : n . Addr . Resource . Type ,
Config : configVal ,
} ,
)
if validateResp . Diagnostics . HasErrors ( ) {
return nil , validateResp . Diagnostics . InConfigBody ( n . Config . Config ) . Err ( )
}
2018-10-02 12:58:49 -05:00
// If we get down here then our configuration is complete and we're read
// to actually call the provider to read the data.
log . Printf ( "[TRACE] EvalReadData: %s configuration is complete, so reading from provider" , absAddr )
err := ctx . Hook ( func ( h Hook ) ( HookAction , error ) {
// We don't have a state yet, so we'll just give the hook an
// empty one to work with.
return h . PreRefresh ( absAddr , states . CurrentGen , cty . NullVal ( cty . DynamicPseudoType ) )
} )
if err != nil {
return nil , err
}
resp := provider . ReadDataSource ( providers . ReadDataSourceRequest {
TypeName : n . Addr . Resource . Type ,
Config : configVal ,
} )
diags = diags . Append ( resp . Diagnostics . InConfigBody ( n . Config . Config ) )
if diags . HasErrors ( ) {
return nil , diags . Err ( )
}
newVal := resp . State
if newVal == cty . NilVal {
// This can happen with incompletely-configured mocks. We'll allow it
// and treat it as an alias for a properly-typed null value.
newVal = cty . NullVal ( schema . ImpliedType ( ) )
}
for _ , err := range newVal . Type ( ) . TestConformance ( schema . ImpliedType ( ) ) {
diags = diags . Append ( tfdiags . Sourceless (
tfdiags . Error ,
"Provider produced invalid object" ,
fmt . Sprintf (
"Provider %q produced an invalid value for %s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker." ,
2020-02-13 14:32:58 -06:00
n . ProviderAddr . Provider . LegacyString ( ) , tfdiags . FormatErrorPrefixed ( err , absAddr . String ( ) ) ,
2018-10-02 12:58:49 -05:00
) ,
) )
}
if diags . HasErrors ( ) {
return nil , diags . Err ( )
}
if newVal . IsNull ( ) {
diags = diags . Append ( tfdiags . Sourceless (
tfdiags . Error ,
"Provider produced null object" ,
fmt . Sprintf (
"Provider %q produced a null value for %s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker." ,
2020-02-13 14:32:58 -06:00
n . ProviderAddr . Provider . LegacyString ( ) , absAddr ,
2018-10-02 12:58:49 -05:00
) ,
) )
}
2019-02-07 18:57:58 -06:00
if ! newVal . IsWhollyKnown ( ) {
diags = diags . Append ( tfdiags . Sourceless (
tfdiags . Error ,
"Provider produced invalid object" ,
fmt . Sprintf (
"Provider %q produced a value for %s that is not wholly known.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker." ,
2020-02-13 14:32:58 -06:00
n . ProviderAddr . Provider . LegacyString ( ) , absAddr ,
2019-02-07 18:57:58 -06:00
) ,
) )
// We'll still save the object, but we need to eliminate any unknown
// values first because we can't serialize them in the state file.
// Note that this may cause set elements to be coalesced if they
// differed only by having unknown values, but we don't worry about
// that here because we're saving the value only for inspection
// purposes; the error we added above will halt the graph walk.
newVal = cty . UnknownAsNull ( newVal )
}
2018-10-02 12:58:49 -05:00
// Since we've completed the read, we actually have no change to make, but
// we'll produce a NoOp one anyway to preserve the usual flow of the
// plan phase and allow it to produce a complete plan.
change = & plans . ResourceInstanceChange {
Addr : absAddr ,
ProviderAddr : n . ProviderAddr ,
Change : plans . Change {
Action : plans . NoOp ,
Before : newVal ,
After : newVal ,
} ,
}
state := & states . ResourceInstanceObject {
2019-10-17 15:05:27 -05:00
Value : change . After ,
Status : states . ObjectReady , // because we completed the read from the provider
2018-10-02 12:58:49 -05:00
}
err = ctx . Hook ( func ( h Hook ) ( HookAction , error ) {
return h . PostRefresh ( absAddr , states . CurrentGen , change . Before , newVal )
} )
if err != nil {
return nil , err
}
if n . OutputChange != nil {
* n . OutputChange = change
}
if n . OutputValue != nil {
* n . OutputValue = change . After
}
if n . OutputConfigValue != nil {
* n . OutputConfigValue = configVal
}
if n . OutputState != nil {
* n . OutputState = state
}
return nil , diags . ErrWithWarnings ( )
}
2016-05-08 01:41:27 -05:00
// EvalReadDataApply is an EvalNode implementation that executes a data
// resource's ReadDataApply method to read data from the data source.
type EvalReadDataApply struct {
2019-10-17 15:05:27 -05:00
Addr addrs . ResourceInstance
Provider * providers . Interface
ProviderAddr addrs . AbsProviderConfig
ProviderSchema * * ProviderSchema
Output * * states . ResourceInstanceObject
Config * configs . Resource
Change * * plans . ResourceInstanceChange
2016-05-08 01:41:27 -05:00
}
func ( n * EvalReadDataApply ) Eval ( ctx EvalContext ) ( interface { } , error ) {
2018-08-28 19:12:06 -05:00
provider := * n . Provider
change := * n . Change
providerSchema := * n . ProviderSchema
absAddr := n . Addr . Absolute ( ctx . Path ( ) )
2016-05-08 01:41:27 -05:00
2018-08-28 19:12:06 -05:00
var diags tfdiags . Diagnostics
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
2018-08-28 19:12:06 -05:00
// If the diff is for *destroying* this resource then we'll
// just drop its state and move on, since data resources don't
// support an actual "destroy" action.
if change != nil && change . Action == plans . Delete {
if n . Output != nil {
* n . Output = nil
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
}
2018-08-28 19:12:06 -05:00
return nil , nil
}
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
2018-08-28 19:12:06 -05:00
// For the purpose of external hooks we present a data apply as a
// "Refresh" rather than an "Apply" because creating a data source
// is presented to users/callers as a "read" operation.
err := ctx . Hook ( func ( h Hook ) ( HookAction , error ) {
// We don't have a state yet, so we'll just give the hook an
// empty one to work with.
return h . PreRefresh ( absAddr , states . CurrentGen , cty . NullVal ( cty . DynamicPseudoType ) )
} )
if err != nil {
return nil , err
}
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
2018-08-28 19:12:06 -05:00
resp := provider . ReadDataSource ( providers . ReadDataSourceRequest {
TypeName : n . Addr . Resource . Type ,
Config : change . After ,
} )
diags = diags . Append ( resp . Diagnostics . InConfigBody ( n . Config . Config ) )
if diags . HasErrors ( ) {
return nil , diags . Err ( )
}
2018-11-27 17:30:18 -06:00
schema , _ := providerSchema . SchemaForResourceAddr ( n . Addr . ContainingResource ( ) )
2018-08-28 19:12:06 -05:00
if schema == nil {
// Should be caught during validation, so we don't bother with a pretty error here
return nil , fmt . Errorf ( "provider does not support data source %q" , n . Addr . Resource . Type )
}
newVal := resp . State
for _ , err := range newVal . Type ( ) . TestConformance ( schema . ImpliedType ( ) ) {
diags = diags . Append ( tfdiags . Sourceless (
tfdiags . Error ,
"Provider produced invalid object" ,
fmt . Sprintf (
"Provider %q planned an invalid value for %s. The result could not be saved.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker." ,
2020-02-13 14:32:58 -06:00
n . ProviderAddr . Provider . LegacyString ( ) , tfdiags . FormatErrorPrefixed ( err , absAddr . String ( ) ) ,
2018-08-28 19:12:06 -05:00
) ,
) )
}
if diags . HasErrors ( ) {
return nil , diags . Err ( )
}
err = ctx . Hook ( func ( h Hook ) ( HookAction , error ) {
return h . PostRefresh ( absAddr , states . CurrentGen , change . Before , newVal )
} )
if err != nil {
return nil , err
}
if n . Output != nil {
* n . Output = & states . ResourceInstanceObject {
2019-10-17 15:05:27 -05:00
Value : newVal ,
Status : states . ObjectReady ,
2016-05-08 03:27:46 -05:00
}
2018-08-28 19:12:06 -05:00
}
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 16:24:45 -05:00
2018-08-28 19:12:06 -05:00
return nil , diags . ErrWithWarnings ( )
2016-05-08 01:41:27 -05:00
}