]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blobdiff - vendor/github.com/hashicorp/terraform/terraform/eval_refresh.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / terraform / eval_refresh.go
index fa2b8126cd0659a2f461020351f1a08bcd4c38dc..03bc948115d963d9ebf1a339e25ae6bd48fe57bc 100644 (file)
@@ -3,53 +3,102 @@ package terraform
 import (
        "fmt"
        "log"
+
+       "github.com/zclconf/go-cty/cty"
+
+       "github.com/hashicorp/terraform/addrs"
+       "github.com/hashicorp/terraform/providers"
+       "github.com/hashicorp/terraform/states"
+       "github.com/hashicorp/terraform/tfdiags"
 )
 
 // EvalRefresh is an EvalNode implementation that does a refresh for
 // a resource.
 type EvalRefresh struct {
-       Provider *ResourceProvider
-       State    **InstanceState
-       Info     *InstanceInfo
-       Output   **InstanceState
+       Addr           addrs.ResourceInstance
+       ProviderAddr   addrs.AbsProviderConfig
+       Provider       *providers.Interface
+       ProviderSchema **ProviderSchema
+       State          **states.ResourceInstanceObject
+       Output         **states.ResourceInstanceObject
 }
 
 // TODO: test
 func (n *EvalRefresh) Eval(ctx EvalContext) (interface{}, error) {
-       provider := *n.Provider
        state := *n.State
+       absAddr := n.Addr.Absolute(ctx.Path())
+
+       var diags tfdiags.Diagnostics
 
        // If we have no state, we don't do any refreshing
        if state == nil {
-               log.Printf("[DEBUG] refresh: %s: no state, not refreshing", n.Info.Id)
-               return nil, nil
+               log.Printf("[DEBUG] refresh: %s: no state, so not refreshing", n.Addr.Absolute(ctx.Path()))
+               return nil, diags.ErrWithWarnings()
+       }
+
+       schema, _ := (*n.ProviderSchema).SchemaForResourceAddr(n.Addr.ContainingResource())
+       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 resource type %q", n.Addr.Resource.Type)
        }
 
        // Call pre-refresh hook
        err := ctx.Hook(func(h Hook) (HookAction, error) {
-               return h.PreRefresh(n.Info, state)
+               return h.PreRefresh(absAddr, states.CurrentGen, state.Value)
        })
        if err != nil {
-               return nil, err
+               return nil, diags.ErrWithWarnings()
        }
 
        // Refresh!
-       state, err = provider.Refresh(n.Info, state)
-       if err != nil {
-               return nil, fmt.Errorf("%s: %s", n.Info.Id, err.Error())
+       priorVal := state.Value
+       req := providers.ReadResourceRequest{
+               TypeName:   n.Addr.Resource.Type,
+               PriorState: priorVal,
        }
 
+       provider := *n.Provider
+       resp := provider.ReadResource(req)
+       diags = diags.Append(resp.Diagnostics)
+       if diags.HasErrors() {
+               return nil, diags.Err()
+       }
+
+       if resp.NewState == cty.NilVal {
+               // This ought not to happen in real cases since it's not possible to
+               // send NilVal over the plugin RPC channel, but it can come up in
+               // tests due to sloppy mocking.
+               panic("new state is cty.NilVal")
+       }
+
+       for _, err := range resp.NewState.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 during refresh: %s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.",
+                               n.ProviderAddr.ProviderConfig.Type, absAddr, tfdiags.FormatError(err),
+                       ),
+               ))
+       }
+       if diags.HasErrors() {
+               return nil, diags.Err()
+       }
+
+       newState := state.DeepCopy()
+       newState.Value = resp.NewState
+
        // Call post-refresh hook
        err = ctx.Hook(func(h Hook) (HookAction, error) {
-               return h.PostRefresh(n.Info, state)
+               return h.PostRefresh(absAddr, states.CurrentGen, priorVal, newState.Value)
        })
        if err != nil {
                return nil, err
        }
 
        if n.Output != nil {
-               *n.Output = state
+               *n.Output = newState
        }
 
-       return nil, nil
+       return nil, diags.ErrWithWarnings()
 }