github.com/miquella/terraform@v0.6.17-0.20160517195040-40db82f25ec0/helper/resource/testing_import_state.go (about)

     1  package resource
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"reflect"
     7  
     8  	"github.com/davecgh/go-spew/spew"
     9  	"github.com/hashicorp/terraform/terraform"
    10  )
    11  
    12  // testStepImportState runs an imort state test step
    13  func testStepImportState(
    14  	opts terraform.ContextOpts,
    15  	state *terraform.State,
    16  	step TestStep) (*terraform.State, error) {
    17  	// Determine the ID to import
    18  	importId := step.ImportStateId
    19  	if importId == "" {
    20  		resource, err := testResource(step, state)
    21  		if err != nil {
    22  			return state, err
    23  		}
    24  
    25  		importId = resource.Primary.ID
    26  	}
    27  
    28  	// Setup the context. We initialize with an empty state. We use the
    29  	// full config for provider configurations.
    30  	mod, err := testModule(opts, step)
    31  	if err != nil {
    32  		return state, err
    33  	}
    34  
    35  	opts.Module = mod
    36  	opts.State = terraform.NewState()
    37  	ctx, err := terraform.NewContext(&opts)
    38  	if err != nil {
    39  		return state, err
    40  	}
    41  
    42  	// Do the import!
    43  	newState, err := ctx.Import(&terraform.ImportOpts{
    44  		// Set the module so that any provider config is loaded
    45  		Module: mod,
    46  
    47  		Targets: []*terraform.ImportTarget{
    48  			&terraform.ImportTarget{
    49  				Addr: step.ResourceName,
    50  				ID:   importId,
    51  			},
    52  		},
    53  	})
    54  	if err != nil {
    55  		log.Printf("[ERROR] Test: ImportState failure: %s", err)
    56  		return state, err
    57  	}
    58  
    59  	// Go through the new state and verify
    60  	if step.ImportStateCheck != nil {
    61  		var states []*terraform.InstanceState
    62  		for _, r := range newState.RootModule().Resources {
    63  			if r.Primary != nil {
    64  				states = append(states, r.Primary)
    65  			}
    66  		}
    67  		if err := step.ImportStateCheck(states); err != nil {
    68  			return state, err
    69  		}
    70  	}
    71  
    72  	// Verify that all the states match
    73  	if step.ImportStateVerify {
    74  		new := newState.RootModule().Resources
    75  		old := state.RootModule().Resources
    76  		for _, r := range new {
    77  			// Find the existing resource
    78  			var oldR *terraform.ResourceState
    79  			for _, r2 := range old {
    80  				if r2.Primary != nil && r2.Primary.ID == r.Primary.ID {
    81  					oldR = r2
    82  					break
    83  				}
    84  			}
    85  			if oldR == nil {
    86  				return state, fmt.Errorf(
    87  					"Failed state verification, resource with ID %s not found",
    88  					r.Primary.ID)
    89  			}
    90  
    91  			// Compare their attributes
    92  			actual := r.Primary.Attributes
    93  			expected := oldR.Primary.Attributes
    94  			if !reflect.DeepEqual(actual, expected) {
    95  				// Determine only the different attributes
    96  				for k, v := range expected {
    97  					if av, ok := actual[k]; ok && v == av {
    98  						delete(expected, k)
    99  						delete(actual, k)
   100  					}
   101  				}
   102  
   103  				spewConf := spew.NewDefaultConfig()
   104  				spewConf.SortKeys = true
   105  				return state, fmt.Errorf(
   106  					"Attributes not equivalent. Difference is shown below. Top is actual, bottom is expected."+
   107  						"\n\n%s\n\n%s",
   108  					spewConf.Sdump(actual), spewConf.Sdump(expected))
   109  			}
   110  		}
   111  	}
   112  
   113  	// Return the old state (non-imported) so we don't change anything.
   114  	return state, nil
   115  }