@ -1,8 +1,11 @@
package testharness
import (
"fmt"
"github.com/hashicorp/terraform/terraform"
"github.com/hashicorp/terraform/tfdiags"
"github.com/zclconf/go-cty/cty"
)
// A contextSetter is something passed to the first argument of a "describe"
@ -41,9 +44,58 @@ type resourceContextSetter struct {
}
func ( s * resourceContextSetter ) AppendContexts ( parent * Context , subject * Subject , ctxs [ ] * Context ) ( [ ] * Context , tfdiags . Diagnostics ) {
// TODO: Set the resource object too
// TODO: If the resource address refers to a resource block with multiple
// instances (e.g. "count" is set) then generate one context for each
// of the instances matched.
return append ( ctxs , parent . WithNameSuffix ( s . Addr . String ( ) ) ) , nil
var diags tfdiags . Diagnostics
// FIXME: Check if a resource with the given address is defined _at all_
// and return an error if not. When we do this, we must handle the special
// case where the resource _is_ defined but has count = 0, in which case
// that is not an error but rather we just generate no child contexts
// at all.
filter := & terraform . StateFilter {
State : subject . state ,
}
// The StateFilter interface is weird: it expects ResourceAddress _strings_
// which it parses itself, rather than letting the caller do its own
// validation. Since we already parsed and validated our resource address,
// we'll need to stringify it here and let this function re-parse it. :/
results , err := filter . Filter ( s . Addr . String ( ) )
if err != nil {
// The only possible error is an invalid address, which should never
// happen because we're passing in a pre-validated address here.
// Thus we won't go to any unusual effort to make this a user-friendly
// diagnostic.
diags = diags . Append ( err )
return ctxs , diags
}
for _ , result := range results {
// Again, for some reason the StateFilter interface deals in strings
// rather than ResourceAddress objects, so once again we end up
// redundantly round-tripping through a string. :(
addr , err := terraform . ParseResourceAddress ( result . Address )
if err != nil {
// Should never happen because this address was just handed
// to us by Terraform core
panic ( fmt . Errorf ( "invalid resource address generated by Terraform core: %s" , err ) )
}
var inst * terraform . InstanceState
switch tr := result . Value . ( type ) {
case * terraform . InstanceState :
inst = tr
default :
// should never happen, but if it does we'll ignore it since
// it's presumably some new type of thing in state.
continue
}
// TODO: convert inst into a cty.Value representing the instance,
// which we can then place in the context for downstream test
// code to use.
_ = inst
ctxs = append ( ctxs , parent . WithResource ( addr , cty . DynamicVal ) )
}
return ctxs , diags
}