github.com/jameswoolfenden/terraform@v0.11.12-beta1/terraform/transform_provider_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/hashicorp/terraform/dag"
     8  )
     9  
    10  func TestProviderTransformer(t *testing.T) {
    11  	mod := testModule(t, "transform-provider-basic")
    12  
    13  	g := Graph{Path: RootModulePath}
    14  	{
    15  		tf := &ConfigTransformer{Module: mod}
    16  		if err := tf.Transform(&g); err != nil {
    17  			t.Fatalf("err: %s", err)
    18  		}
    19  	}
    20  
    21  	{
    22  		transform := &AttachResourceConfigTransformer{Module: mod}
    23  		if err := transform.Transform(&g); err != nil {
    24  			t.Fatalf("err: %s", err)
    25  		}
    26  	}
    27  
    28  	{
    29  		transform := &MissingProviderTransformer{Providers: []string{"aws"}}
    30  		if err := transform.Transform(&g); err != nil {
    31  			t.Fatalf("err: %s", err)
    32  		}
    33  	}
    34  
    35  	transform := &ProviderTransformer{}
    36  	if err := transform.Transform(&g); err != nil {
    37  		t.Fatalf("err: %s", err)
    38  	}
    39  
    40  	actual := strings.TrimSpace(g.String())
    41  	expected := strings.TrimSpace(testTransformProviderBasicStr)
    42  	if actual != expected {
    43  		t.Fatalf("bad:\n\n%s", actual)
    44  	}
    45  }
    46  
    47  func TestProviderTransformer_moduleChild(t *testing.T) {
    48  	g := Graph{Path: RootModulePath}
    49  
    50  	{
    51  		tf := &ImportStateTransformer{
    52  			Targets: []*ImportTarget{
    53  				&ImportTarget{
    54  					Addr: "module.moo.foo_instance.qux",
    55  					ID:   "bar",
    56  				},
    57  			},
    58  		}
    59  		if err := tf.Transform(&g); err != nil {
    60  			t.Fatalf("err: %s", err)
    61  		}
    62  	}
    63  
    64  	{
    65  		tf := &MissingProviderTransformer{Providers: []string{"foo", "bar"}}
    66  		if err := tf.Transform(&g); err != nil {
    67  			t.Fatalf("err: %s", err)
    68  		}
    69  	}
    70  
    71  	{
    72  		tf := &ProviderTransformer{}
    73  		if err := tf.Transform(&g); err != nil {
    74  			t.Fatalf("err: %s", err)
    75  		}
    76  	}
    77  
    78  	actual := strings.TrimSpace(g.String())
    79  	expected := strings.TrimSpace(testTransformProviderModuleChildStr)
    80  	if actual != expected {
    81  		t.Fatalf("bad:\n\n%s", actual)
    82  	}
    83  }
    84  
    85  func TestCloseProviderTransformer(t *testing.T) {
    86  	mod := testModule(t, "transform-provider-basic")
    87  
    88  	g := Graph{Path: RootModulePath}
    89  	{
    90  		tf := &ConfigTransformer{Module: mod}
    91  		if err := tf.Transform(&g); err != nil {
    92  			t.Fatalf("err: %s", err)
    93  		}
    94  	}
    95  
    96  	{
    97  		transform := &AttachResourceConfigTransformer{Module: mod}
    98  		if err := transform.Transform(&g); err != nil {
    99  			t.Fatalf("err: %s", err)
   100  		}
   101  	}
   102  
   103  	{
   104  		transform := &MissingProviderTransformer{Providers: []string{"aws"}}
   105  		if err := transform.Transform(&g); err != nil {
   106  			t.Fatalf("err: %s", err)
   107  		}
   108  	}
   109  
   110  	{
   111  		transform := &ProviderTransformer{}
   112  		if err := transform.Transform(&g); err != nil {
   113  			t.Fatalf("err: %s", err)
   114  		}
   115  	}
   116  
   117  	{
   118  		transform := &CloseProviderTransformer{}
   119  		if err := transform.Transform(&g); err != nil {
   120  			t.Fatalf("err: %s", err)
   121  		}
   122  	}
   123  
   124  	actual := strings.TrimSpace(g.String())
   125  	expected := strings.TrimSpace(testTransformCloseProviderBasicStr)
   126  	if actual != expected {
   127  		t.Fatalf("bad:\n\n%s", actual)
   128  	}
   129  }
   130  
   131  func TestCloseProviderTransformer_withTargets(t *testing.T) {
   132  	mod := testModule(t, "transform-provider-basic")
   133  
   134  	g := Graph{Path: RootModulePath}
   135  	transforms := []GraphTransformer{
   136  		&ConfigTransformer{Module: mod},
   137  		&MissingProviderTransformer{Providers: []string{"aws"}},
   138  		&ProviderTransformer{},
   139  		&CloseProviderTransformer{},
   140  		&TargetsTransformer{
   141  			Targets: []string{"something.else"},
   142  		},
   143  	}
   144  
   145  	for _, tr := range transforms {
   146  		if err := tr.Transform(&g); err != nil {
   147  			t.Fatalf("err: %s", err)
   148  		}
   149  	}
   150  
   151  	actual := strings.TrimSpace(g.String())
   152  	expected := strings.TrimSpace(``)
   153  	if actual != expected {
   154  		t.Fatalf("expected:%s\n\ngot:\n\n%s", expected, actual)
   155  	}
   156  }
   157  
   158  func TestMissingProviderTransformer(t *testing.T) {
   159  	mod := testModule(t, "transform-provider-missing")
   160  
   161  	g := Graph{Path: RootModulePath}
   162  	{
   163  		tf := &ConfigTransformer{Module: mod}
   164  		if err := tf.Transform(&g); err != nil {
   165  			t.Fatalf("err: %s", err)
   166  		}
   167  	}
   168  
   169  	{
   170  		transform := &AttachResourceConfigTransformer{Module: mod}
   171  		if err := transform.Transform(&g); err != nil {
   172  			t.Fatalf("err: %s", err)
   173  		}
   174  	}
   175  
   176  	{
   177  		transform := &MissingProviderTransformer{Providers: []string{"aws", "foo", "bar"}}
   178  		if err := transform.Transform(&g); err != nil {
   179  			t.Fatalf("err: %s", err)
   180  		}
   181  	}
   182  
   183  	{
   184  		transform := &ProviderTransformer{}
   185  		if err := transform.Transform(&g); err != nil {
   186  			t.Fatalf("err: %s", err)
   187  		}
   188  	}
   189  
   190  	{
   191  		transform := &CloseProviderTransformer{}
   192  		if err := transform.Transform(&g); err != nil {
   193  			t.Fatalf("err: %s", err)
   194  		}
   195  	}
   196  
   197  	actual := strings.TrimSpace(g.String())
   198  	expected := strings.TrimSpace(testTransformMissingProviderBasicStr)
   199  	if actual != expected {
   200  		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
   201  	}
   202  }
   203  
   204  func TestMissingProviderTransformer_grandchildMissing(t *testing.T) {
   205  	mod := testModule(t, "transform-provider-missing-grandchild")
   206  
   207  	concrete := func(a *NodeAbstractProvider) dag.Vertex { return a }
   208  
   209  	g := Graph{Path: RootModulePath}
   210  	{
   211  		tf := &ConfigTransformer{Module: mod}
   212  		if err := tf.Transform(&g); err != nil {
   213  			t.Fatalf("err: %s", err)
   214  		}
   215  	}
   216  
   217  	{
   218  		transform := &AttachResourceConfigTransformer{Module: mod}
   219  		if err := transform.Transform(&g); err != nil {
   220  			t.Fatalf("err: %s", err)
   221  		}
   222  	}
   223  
   224  	{
   225  		transform := TransformProviders([]string{"aws", "foo", "bar"}, concrete, mod)
   226  		if err := transform.Transform(&g); err != nil {
   227  			t.Fatalf("err: %s", err)
   228  		}
   229  	}
   230  	{
   231  		transform := &TransitiveReductionTransformer{}
   232  		if err := transform.Transform(&g); err != nil {
   233  			t.Fatalf("err: %s", err)
   234  		}
   235  	}
   236  
   237  	actual := strings.TrimSpace(g.String())
   238  	expected := strings.TrimSpace(testTransformMissingGrandchildProviderStr)
   239  	if actual != expected {
   240  		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
   241  	}
   242  }
   243  
   244  func TestMissingProviderTransformer_moduleChild(t *testing.T) {
   245  	g := Graph{Path: RootModulePath}
   246  
   247  	// We use the import state transformer since at the time of writing
   248  	// this test it is the first and only transformer that will introduce
   249  	// multiple module-path nodes at a single go.
   250  	{
   251  		tf := &ImportStateTransformer{
   252  			Targets: []*ImportTarget{
   253  				&ImportTarget{
   254  					Addr: "module.moo.foo_instance.qux",
   255  					ID:   "bar",
   256  				},
   257  			},
   258  		}
   259  		if err := tf.Transform(&g); err != nil {
   260  			t.Fatalf("err: %s", err)
   261  		}
   262  	}
   263  
   264  	{
   265  		tf := &MissingProviderTransformer{Providers: []string{"foo", "bar"}}
   266  		if err := tf.Transform(&g); err != nil {
   267  			t.Fatalf("err: %s", err)
   268  		}
   269  	}
   270  
   271  	actual := strings.TrimSpace(g.String())
   272  	expected := strings.TrimSpace(testTransformMissingProviderModuleChildStr)
   273  	if actual != expected {
   274  		t.Fatalf("bad:\n\n%s", actual)
   275  	}
   276  }
   277  
   278  func TestMissingProviderTransformer_moduleGrandchild(t *testing.T) {
   279  	g := Graph{Path: RootModulePath}
   280  
   281  	// We use the import state transformer since at the time of writing
   282  	// this test it is the first and only transformer that will introduce
   283  	// multiple module-path nodes at a single go.
   284  	{
   285  		tf := &ImportStateTransformer{
   286  			Targets: []*ImportTarget{
   287  				&ImportTarget{
   288  					Addr: "module.a.module.b.foo_instance.qux",
   289  					ID:   "bar",
   290  				},
   291  			},
   292  		}
   293  		if err := tf.Transform(&g); err != nil {
   294  			t.Fatalf("err: %s", err)
   295  		}
   296  	}
   297  
   298  	{
   299  		tf := &MissingProviderTransformer{Providers: []string{"foo", "bar"}}
   300  		if err := tf.Transform(&g); err != nil {
   301  			t.Fatalf("err: %s", err)
   302  		}
   303  	}
   304  
   305  	actual := strings.TrimSpace(g.String())
   306  	expected := strings.TrimSpace(testTransformMissingProviderModuleGrandchildStr)
   307  	if actual != expected {
   308  		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
   309  	}
   310  }
   311  
   312  func TestParentProviderTransformer(t *testing.T) {
   313  	g := Graph{Path: RootModulePath}
   314  
   315  	// Introduce a cihld module
   316  	{
   317  		tf := &ImportStateTransformer{
   318  			Targets: []*ImportTarget{
   319  				&ImportTarget{
   320  					Addr: "module.moo.foo_instance.qux",
   321  					ID:   "bar",
   322  				},
   323  			},
   324  		}
   325  		if err := tf.Transform(&g); err != nil {
   326  			t.Fatalf("err: %s", err)
   327  		}
   328  	}
   329  
   330  	// Add the missing modules
   331  	{
   332  		tf := &MissingProviderTransformer{Providers: []string{"foo", "bar"}}
   333  		if err := tf.Transform(&g); err != nil {
   334  			t.Fatalf("err: %s", err)
   335  		}
   336  	}
   337  
   338  	// Connect parents
   339  	{
   340  		tf := &ParentProviderTransformer{}
   341  		if err := tf.Transform(&g); err != nil {
   342  			t.Fatalf("err: %s", err)
   343  		}
   344  	}
   345  
   346  	actual := strings.TrimSpace(g.String())
   347  	expected := strings.TrimSpace(testTransformParentProviderStr)
   348  	if actual != expected {
   349  		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
   350  	}
   351  }
   352  
   353  func TestParentProviderTransformer_moduleGrandchild(t *testing.T) {
   354  	g := Graph{Path: RootModulePath}
   355  
   356  	// We use the import state transformer since at the time of writing
   357  	// this test it is the first and only transformer that will introduce
   358  	// multiple module-path nodes at a single go.
   359  	{
   360  		tf := &ImportStateTransformer{
   361  			Targets: []*ImportTarget{
   362  				&ImportTarget{
   363  					Addr: "module.a.module.b.foo_instance.qux",
   364  					ID:   "bar",
   365  				},
   366  			},
   367  		}
   368  		if err := tf.Transform(&g); err != nil {
   369  			t.Fatalf("err: %s", err)
   370  		}
   371  	}
   372  
   373  	{
   374  		tf := &MissingProviderTransformer{Providers: []string{"foo", "bar"}}
   375  		if err := tf.Transform(&g); err != nil {
   376  			t.Fatalf("err: %s", err)
   377  		}
   378  	}
   379  
   380  	// Connect parents
   381  	{
   382  		tf := &ParentProviderTransformer{}
   383  		if err := tf.Transform(&g); err != nil {
   384  			t.Fatalf("err: %s", err)
   385  		}
   386  	}
   387  
   388  	actual := strings.TrimSpace(g.String())
   389  	expected := strings.TrimSpace(testTransformParentProviderModuleGrandchildStr)
   390  	if actual != expected {
   391  		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
   392  	}
   393  }
   394  
   395  func TestPruneProviderTransformer(t *testing.T) {
   396  	mod := testModule(t, "transform-provider-prune")
   397  
   398  	g := Graph{Path: RootModulePath}
   399  	{
   400  		tf := &ConfigTransformer{Module: mod}
   401  		if err := tf.Transform(&g); err != nil {
   402  			t.Fatalf("err: %s", err)
   403  		}
   404  	}
   405  
   406  	{
   407  		transform := &AttachResourceConfigTransformer{Module: mod}
   408  		if err := transform.Transform(&g); err != nil {
   409  			t.Fatalf("err: %s", err)
   410  		}
   411  	}
   412  
   413  	{
   414  		transform := &MissingProviderTransformer{Providers: []string{"foo"}}
   415  		if err := transform.Transform(&g); err != nil {
   416  			t.Fatalf("err: %s", err)
   417  		}
   418  	}
   419  
   420  	{
   421  		transform := &ProviderTransformer{}
   422  		if err := transform.Transform(&g); err != nil {
   423  			t.Fatalf("err: %s", err)
   424  		}
   425  	}
   426  
   427  	{
   428  		transform := &CloseProviderTransformer{}
   429  		if err := transform.Transform(&g); err != nil {
   430  			t.Fatalf("err: %s", err)
   431  		}
   432  	}
   433  
   434  	{
   435  		transform := &PruneProviderTransformer{}
   436  		if err := transform.Transform(&g); err != nil {
   437  			t.Fatalf("err: %s", err)
   438  		}
   439  	}
   440  
   441  	actual := strings.TrimSpace(g.String())
   442  	expected := strings.TrimSpace(testTransformPruneProviderBasicStr)
   443  	if actual != expected {
   444  		t.Fatalf("bad:\n\n%s", actual)
   445  	}
   446  }
   447  
   448  // the child module resource is attached to the configured parent provider
   449  func TestProviderConfigTransformer_parentProviders(t *testing.T) {
   450  	mod := testModule(t, "transform-provider-inherit")
   451  	concrete := func(a *NodeAbstractProvider) dag.Vertex { return a }
   452  
   453  	g := Graph{Path: RootModulePath}
   454  	{
   455  		tf := &ConfigTransformer{Module: mod}
   456  		if err := tf.Transform(&g); err != nil {
   457  			t.Fatalf("err: %s", err)
   458  		}
   459  	}
   460  	{
   461  		tf := &AttachResourceConfigTransformer{Module: mod}
   462  		if err := tf.Transform(&g); err != nil {
   463  			t.Fatalf("err: %s", err)
   464  		}
   465  	}
   466  
   467  	{
   468  		tf := TransformProviders([]string{"aws"}, concrete, mod)
   469  		if err := tf.Transform(&g); err != nil {
   470  			t.Fatalf("err: %s", err)
   471  		}
   472  	}
   473  
   474  	actual := strings.TrimSpace(g.String())
   475  	expected := strings.TrimSpace(testTransformModuleProviderConfigStr)
   476  	if actual != expected {
   477  		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
   478  	}
   479  }
   480  
   481  // the child module resource is attached to the configured grand-parent provider
   482  func TestProviderConfigTransformer_grandparentProviders(t *testing.T) {
   483  	mod := testModule(t, "transform-provider-grandchild-inherit")
   484  	concrete := func(a *NodeAbstractProvider) dag.Vertex { return a }
   485  
   486  	g := Graph{Path: RootModulePath}
   487  	{
   488  		tf := &ConfigTransformer{Module: mod}
   489  		if err := tf.Transform(&g); err != nil {
   490  			t.Fatalf("err: %s", err)
   491  		}
   492  	}
   493  	{
   494  		tf := &AttachResourceConfigTransformer{Module: mod}
   495  		if err := tf.Transform(&g); err != nil {
   496  			t.Fatalf("err: %s", err)
   497  		}
   498  	}
   499  
   500  	{
   501  		tf := TransformProviders([]string{"aws"}, concrete, mod)
   502  		if err := tf.Transform(&g); err != nil {
   503  			t.Fatalf("err: %s", err)
   504  		}
   505  	}
   506  
   507  	actual := strings.TrimSpace(g.String())
   508  	expected := strings.TrimSpace(testTransformModuleProviderGrandparentStr)
   509  	if actual != expected {
   510  		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
   511  	}
   512  }
   513  
   514  // pass a specific provider into a module using it implicitly
   515  func TestProviderConfigTransformer_implicitModule(t *testing.T) {
   516  	mod := testModule(t, "transform-provider-implicit-module")
   517  	concrete := func(a *NodeAbstractProvider) dag.Vertex { return a }
   518  
   519  	g := Graph{Path: RootModulePath}
   520  	{
   521  		tf := &ConfigTransformer{Module: mod}
   522  		if err := tf.Transform(&g); err != nil {
   523  			t.Fatalf("err: %s", err)
   524  		}
   525  	}
   526  	{
   527  		tf := &AttachResourceConfigTransformer{Module: mod}
   528  		if err := tf.Transform(&g); err != nil {
   529  			t.Fatalf("err: %s", err)
   530  		}
   531  	}
   532  	{
   533  		tf := TransformProviders([]string{"aws"}, concrete, mod)
   534  		if err := tf.Transform(&g); err != nil {
   535  			t.Fatalf("err: %s", err)
   536  		}
   537  	}
   538  
   539  	actual := strings.TrimSpace(g.String())
   540  	expected := strings.TrimSpace(`module.mod.aws_instance.bar
   541    provider.aws.foo
   542  provider.aws.foo`)
   543  	if actual != expected {
   544  		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
   545  	}
   546  }
   547  
   548  // error out when a non-existent provider is named in a module providers map
   549  func TestProviderConfigTransformer_invalidProvider(t *testing.T) {
   550  	mod := testModule(t, "transform-provider-invalid")
   551  	concrete := func(a *NodeAbstractProvider) dag.Vertex { return a }
   552  
   553  	g := Graph{Path: RootModulePath}
   554  	{
   555  		tf := &ConfigTransformer{Module: mod}
   556  		if err := tf.Transform(&g); err != nil {
   557  			t.Fatalf("err: %s", err)
   558  		}
   559  	}
   560  	{
   561  		tf := &AttachResourceConfigTransformer{Module: mod}
   562  		if err := tf.Transform(&g); err != nil {
   563  			t.Fatalf("err: %s", err)
   564  		}
   565  	}
   566  
   567  	tf := TransformProviders([]string{"aws"}, concrete, mod)
   568  	err := tf.Transform(&g)
   569  	if err == nil {
   570  		t.Fatal("expected missing provider error")
   571  	}
   572  	if !strings.Contains(err.Error(), "provider.aws.foo") {
   573  		t.Fatalf("error should reference missing provider, got: %s", err)
   574  	}
   575  }
   576  
   577  const testTransformProviderBasicStr = `
   578  aws_instance.web
   579    provider.aws
   580  provider.aws
   581  `
   582  
   583  const testTransformCloseProviderBasicStr = `
   584  aws_instance.web
   585    provider.aws
   586  provider.aws
   587  provider.aws (close)
   588    aws_instance.web
   589    provider.aws
   590  `
   591  
   592  const testTransformMissingProviderBasicStr = `
   593  aws_instance.web
   594    provider.aws
   595  foo_instance.web
   596    provider.foo
   597  provider.aws
   598  provider.aws (close)
   599    aws_instance.web
   600    provider.aws
   601  provider.foo
   602  provider.foo (close)
   603    foo_instance.web
   604    provider.foo
   605  `
   606  
   607  const testTransformMissingGrandchildProviderStr = `
   608  module.sub.module.subsub.bar_instance.two
   609    provider.bar
   610  module.sub.module.subsub.foo_instance.one
   611    module.sub.provider.foo
   612  module.sub.provider.foo
   613  provider.bar
   614  `
   615  
   616  const testTransformMissingProviderModuleChildStr = `
   617  module.moo.foo_instance.qux (import id: bar)
   618  provider.foo
   619  `
   620  
   621  const testTransformMissingProviderModuleGrandchildStr = `
   622  module.a.module.b.foo_instance.qux (import id: bar)
   623  provider.foo
   624  `
   625  
   626  const testTransformParentProviderStr = `
   627  module.moo.foo_instance.qux (import id: bar)
   628  provider.foo
   629  `
   630  
   631  const testTransformParentProviderModuleGrandchildStr = `
   632  module.a.module.b.foo_instance.qux (import id: bar)
   633  provider.foo
   634  `
   635  
   636  const testTransformProviderModuleChildStr = `
   637  module.moo.foo_instance.qux (import id: bar)
   638    provider.foo
   639  provider.foo
   640  `
   641  
   642  const testTransformPruneProviderBasicStr = `
   643  foo_instance.web
   644    provider.foo
   645  provider.foo
   646  provider.foo (close)
   647    foo_instance.web
   648    provider.foo
   649  `
   650  
   651  const testTransformDisableProviderBasicStr = `
   652  module.child
   653    provider.aws (disabled)
   654    var.foo
   655  provider.aws (close)
   656    module.child
   657    provider.aws (disabled)
   658  provider.aws (disabled)
   659  var.foo
   660  `
   661  
   662  const testTransformDisableProviderKeepStr = `
   663  aws_instance.foo
   664    provider.aws
   665  module.child
   666    provider.aws
   667    var.foo
   668  provider.aws
   669  provider.aws (close)
   670    aws_instance.foo
   671    module.child
   672    provider.aws
   673  var.foo
   674  `
   675  
   676  const testTransformModuleProviderConfigStr = `
   677  module.child.aws_instance.thing
   678    provider.aws.foo
   679  provider.aws.foo
   680  `
   681  
   682  const testTransformModuleProviderGrandparentStr = `
   683  module.child.module.grandchild.aws_instance.baz
   684    provider.aws.foo
   685  provider.aws.foo
   686  `