github.com/muratcelep/terraform@v1.1.0-beta2-not-internal-4/not-internal/terraform/transform_provider_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/muratcelep/terraform/not-internal/addrs"
     9  	"github.com/muratcelep/terraform/not-internal/configs"
    10  	"github.com/muratcelep/terraform/not-internal/dag"
    11  )
    12  
    13  func testProviderTransformerGraph(t *testing.T, cfg *configs.Config) *Graph {
    14  	t.Helper()
    15  
    16  	g := &Graph{Path: addrs.RootModuleInstance}
    17  	ct := &ConfigTransformer{Config: cfg}
    18  	if err := ct.Transform(g); err != nil {
    19  		t.Fatal(err)
    20  	}
    21  	arct := &AttachResourceConfigTransformer{Config: cfg}
    22  	if err := arct.Transform(g); err != nil {
    23  		t.Fatal(err)
    24  	}
    25  
    26  	return g
    27  }
    28  
    29  func TestProviderTransformer(t *testing.T) {
    30  	mod := testModule(t, "transform-provider-basic")
    31  
    32  	g := testProviderTransformerGraph(t, mod)
    33  	{
    34  		transform := &MissingProviderTransformer{}
    35  		if err := transform.Transform(g); err != nil {
    36  			t.Fatalf("err: %s", err)
    37  		}
    38  	}
    39  
    40  	transform := &ProviderTransformer{}
    41  	if err := transform.Transform(g); err != nil {
    42  		t.Fatalf("err: %s", err)
    43  	}
    44  
    45  	actual := strings.TrimSpace(g.String())
    46  	expected := strings.TrimSpace(testTransformProviderBasicStr)
    47  	if actual != expected {
    48  		t.Fatalf("bad:\n\n%s", actual)
    49  	}
    50  }
    51  
    52  func TestProviderTransformer_ImportModuleChild(t *testing.T) {
    53  	mod := testModule(t, "import-module")
    54  
    55  	g := testProviderTransformerGraph(t, mod)
    56  
    57  	{
    58  		tf := &ImportStateTransformer{
    59  			Config: mod,
    60  			Targets: []*ImportTarget{
    61  				&ImportTarget{
    62  					Addr: addrs.RootModuleInstance.
    63  						Child("child", addrs.NoKey).
    64  						ResourceInstance(
    65  							addrs.ManagedResourceMode,
    66  							"aws_instance",
    67  							"foo",
    68  							addrs.NoKey,
    69  						),
    70  					ID: "bar",
    71  				},
    72  			},
    73  		}
    74  
    75  		if err := tf.Transform(g); err != nil {
    76  			t.Fatalf("err: %s", err)
    77  		}
    78  		t.Logf("graph after ImportStateTransformer:\n%s", g.String())
    79  	}
    80  
    81  	{
    82  		tf := &MissingProviderTransformer{}
    83  		if err := tf.Transform(g); err != nil {
    84  			t.Fatalf("err: %s", err)
    85  		}
    86  		t.Logf("graph after MissingProviderTransformer:\n%s", g.String())
    87  	}
    88  
    89  	{
    90  		tf := &ProviderTransformer{}
    91  		if err := tf.Transform(g); err != nil {
    92  			t.Fatalf("err: %s", err)
    93  		}
    94  		t.Logf("graph after ProviderTransformer:\n%s", g.String())
    95  	}
    96  
    97  	actual := strings.TrimSpace(g.String())
    98  	expected := strings.TrimSpace(testTransformImportModuleChildStr)
    99  	if actual != expected {
   100  		t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
   101  	}
   102  }
   103  
   104  // Test providers with FQNs that do not match the typeName
   105  func TestProviderTransformer_fqns(t *testing.T) {
   106  	for _, mod := range []string{"fqns", "fqns-module"} {
   107  		mod := testModule(t, fmt.Sprintf("transform-provider-%s", mod))
   108  
   109  		g := testProviderTransformerGraph(t, mod)
   110  		{
   111  			transform := &MissingProviderTransformer{Config: mod}
   112  			if err := transform.Transform(g); err != nil {
   113  				t.Fatalf("err: %s", err)
   114  			}
   115  		}
   116  
   117  		transform := &ProviderTransformer{Config: mod}
   118  		if err := transform.Transform(g); err != nil {
   119  			t.Fatalf("err: %s", err)
   120  		}
   121  
   122  		actual := strings.TrimSpace(g.String())
   123  		expected := strings.TrimSpace(testTransformProviderBasicStr)
   124  		if actual != expected {
   125  			t.Fatalf("bad:\n\n%s", actual)
   126  		}
   127  	}
   128  }
   129  
   130  func TestCloseProviderTransformer(t *testing.T) {
   131  	mod := testModule(t, "transform-provider-basic")
   132  	g := testProviderTransformerGraph(t, mod)
   133  
   134  	{
   135  		transform := &MissingProviderTransformer{}
   136  		if err := transform.Transform(g); err != nil {
   137  			t.Fatalf("err: %s", err)
   138  		}
   139  	}
   140  
   141  	{
   142  		transform := &ProviderTransformer{}
   143  		if err := transform.Transform(g); err != nil {
   144  			t.Fatalf("err: %s", err)
   145  		}
   146  	}
   147  
   148  	{
   149  		transform := &CloseProviderTransformer{}
   150  		if err := transform.Transform(g); err != nil {
   151  			t.Fatalf("err: %s", err)
   152  		}
   153  	}
   154  
   155  	actual := strings.TrimSpace(g.String())
   156  	expected := strings.TrimSpace(testTransformCloseProviderBasicStr)
   157  	if actual != expected {
   158  		t.Fatalf("bad:\n\n%s", actual)
   159  	}
   160  }
   161  
   162  func TestCloseProviderTransformer_withTargets(t *testing.T) {
   163  	mod := testModule(t, "transform-provider-basic")
   164  
   165  	g := testProviderTransformerGraph(t, mod)
   166  	transforms := []GraphTransformer{
   167  		&MissingProviderTransformer{},
   168  		&ProviderTransformer{},
   169  		&CloseProviderTransformer{},
   170  		&TargetsTransformer{
   171  			Targets: []addrs.Targetable{
   172  				addrs.RootModuleInstance.Resource(
   173  					addrs.ManagedResourceMode, "something", "else",
   174  				),
   175  			},
   176  		},
   177  	}
   178  
   179  	for _, tr := range transforms {
   180  		if err := tr.Transform(g); err != nil {
   181  			t.Fatalf("err: %s", err)
   182  		}
   183  	}
   184  
   185  	actual := strings.TrimSpace(g.String())
   186  	expected := strings.TrimSpace(``)
   187  	if actual != expected {
   188  		t.Fatalf("expected:%s\n\ngot:\n\n%s", expected, actual)
   189  	}
   190  }
   191  
   192  func TestMissingProviderTransformer(t *testing.T) {
   193  	mod := testModule(t, "transform-provider-missing")
   194  
   195  	g := testProviderTransformerGraph(t, mod)
   196  	{
   197  		transform := &MissingProviderTransformer{}
   198  		if err := transform.Transform(g); err != nil {
   199  			t.Fatalf("err: %s", err)
   200  		}
   201  	}
   202  
   203  	{
   204  		transform := &ProviderTransformer{}
   205  		if err := transform.Transform(g); err != nil {
   206  			t.Fatalf("err: %s", err)
   207  		}
   208  	}
   209  
   210  	{
   211  		transform := &CloseProviderTransformer{}
   212  		if err := transform.Transform(g); err != nil {
   213  			t.Fatalf("err: %s", err)
   214  		}
   215  	}
   216  
   217  	actual := strings.TrimSpace(g.String())
   218  	expected := strings.TrimSpace(testTransformMissingProviderBasicStr)
   219  	if actual != expected {
   220  		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
   221  	}
   222  }
   223  
   224  func TestMissingProviderTransformer_grandchildMissing(t *testing.T) {
   225  	mod := testModule(t, "transform-provider-missing-grandchild")
   226  
   227  	concrete := func(a *NodeAbstractProvider) dag.Vertex { return a }
   228  
   229  	g := testProviderTransformerGraph(t, mod)
   230  	{
   231  		transform := transformProviders(concrete, mod)
   232  		if err := transform.Transform(g); err != nil {
   233  			t.Fatalf("err: %s", err)
   234  		}
   235  	}
   236  	{
   237  		transform := &TransitiveReductionTransformer{}
   238  		if err := transform.Transform(g); err != nil {
   239  			t.Fatalf("err: %s", err)
   240  		}
   241  	}
   242  
   243  	actual := strings.TrimSpace(g.String())
   244  	expected := strings.TrimSpace(testTransformMissingGrandchildProviderStr)
   245  	if actual != expected {
   246  		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
   247  	}
   248  }
   249  
   250  func TestPruneProviderTransformer(t *testing.T) {
   251  	mod := testModule(t, "transform-provider-prune")
   252  
   253  	g := testProviderTransformerGraph(t, mod)
   254  	{
   255  		transform := &MissingProviderTransformer{}
   256  		if err := transform.Transform(g); err != nil {
   257  			t.Fatalf("err: %s", err)
   258  		}
   259  	}
   260  
   261  	{
   262  		transform := &ProviderTransformer{}
   263  		if err := transform.Transform(g); err != nil {
   264  			t.Fatalf("err: %s", err)
   265  		}
   266  	}
   267  
   268  	{
   269  		transform := &CloseProviderTransformer{}
   270  		if err := transform.Transform(g); err != nil {
   271  			t.Fatalf("err: %s", err)
   272  		}
   273  	}
   274  
   275  	{
   276  		transform := &PruneProviderTransformer{}
   277  		if err := transform.Transform(g); err != nil {
   278  			t.Fatalf("err: %s", err)
   279  		}
   280  	}
   281  
   282  	actual := strings.TrimSpace(g.String())
   283  	expected := strings.TrimSpace(testTransformPruneProviderBasicStr)
   284  	if actual != expected {
   285  		t.Fatalf("bad:\n\n%s", actual)
   286  	}
   287  }
   288  
   289  // the child module resource is attached to the configured parent provider
   290  func TestProviderConfigTransformer_parentProviders(t *testing.T) {
   291  	mod := testModule(t, "transform-provider-inherit")
   292  	concrete := func(a *NodeAbstractProvider) dag.Vertex { return a }
   293  
   294  	g := testProviderTransformerGraph(t, mod)
   295  	{
   296  		tf := transformProviders(concrete, mod)
   297  		if err := tf.Transform(g); err != nil {
   298  			t.Fatalf("err: %s", err)
   299  		}
   300  	}
   301  
   302  	actual := strings.TrimSpace(g.String())
   303  	expected := strings.TrimSpace(testTransformModuleProviderConfigStr)
   304  	if actual != expected {
   305  		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
   306  	}
   307  }
   308  
   309  // the child module resource is attached to the configured grand-parent provider
   310  func TestProviderConfigTransformer_grandparentProviders(t *testing.T) {
   311  	mod := testModule(t, "transform-provider-grandchild-inherit")
   312  	concrete := func(a *NodeAbstractProvider) dag.Vertex { return a }
   313  
   314  	g := testProviderTransformerGraph(t, mod)
   315  	{
   316  		tf := transformProviders(concrete, mod)
   317  		if err := tf.Transform(g); err != nil {
   318  			t.Fatalf("err: %s", err)
   319  		}
   320  	}
   321  
   322  	actual := strings.TrimSpace(g.String())
   323  	expected := strings.TrimSpace(testTransformModuleProviderGrandparentStr)
   324  	if actual != expected {
   325  		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
   326  	}
   327  }
   328  
   329  func TestProviderConfigTransformer_inheritOldSkool(t *testing.T) {
   330  	mod := testModuleInline(t, map[string]string{
   331  		"main.tf": `
   332  provider "test" {
   333    test_string = "config"
   334  }
   335  
   336  module "moda" {
   337    source = "./moda"
   338  }
   339  `,
   340  
   341  		"moda/main.tf": `
   342  resource "test_object" "a" {
   343  }
   344  `,
   345  	})
   346  	concrete := func(a *NodeAbstractProvider) dag.Vertex { return a }
   347  
   348  	g := testProviderTransformerGraph(t, mod)
   349  	{
   350  		tf := transformProviders(concrete, mod)
   351  		if err := tf.Transform(g); err != nil {
   352  			t.Fatalf("err: %s", err)
   353  		}
   354  	}
   355  
   356  	expected := `module.moda.test_object.a
   357    provider["registry.terraform.io/hashicorp/test"]
   358  provider["registry.terraform.io/hashicorp/test"]`
   359  
   360  	actual := strings.TrimSpace(g.String())
   361  	if actual != expected {
   362  		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
   363  	}
   364  }
   365  
   366  // Verify that configurations which are not recommended yet supported still work
   367  func TestProviderConfigTransformer_nestedModuleProviders(t *testing.T) {
   368  	mod := testModuleInline(t, map[string]string{
   369  		"main.tf": `
   370  terraform {
   371    required_providers {
   372      test = {
   373        source = "registry.terraform.io/hashicorp/test"
   374  	}
   375    }
   376  }
   377  
   378  provider "test" {
   379    alias = "z"
   380    test_string = "config"
   381  }
   382  
   383  module "moda" {
   384    source = "./moda"
   385    providers = {
   386      test.x = test.z
   387    }
   388  }
   389  `,
   390  
   391  		"moda/main.tf": `
   392  terraform {
   393    required_providers {
   394      test = {
   395        source = "registry.terraform.io/hashicorp/test"
   396        configuration_aliases = [ test.x ]
   397  	}
   398    }
   399  }
   400  
   401  provider "test" {
   402    test_string = "config"
   403  }
   404  
   405  // this should connect to this module's provider
   406  resource "test_object" "a" {
   407  }
   408  
   409  resource "test_object" "x" {
   410    provider = test.x
   411  }
   412  
   413  module "modb" {
   414    source = "./modb"
   415  }
   416  `,
   417  
   418  		"moda/modb/main.tf": `
   419  # this should end up with the provider from the parent module
   420  resource "test_object" "a" {
   421  }
   422  `,
   423  	})
   424  	concrete := func(a *NodeAbstractProvider) dag.Vertex { return a }
   425  
   426  	g := testProviderTransformerGraph(t, mod)
   427  	{
   428  		tf := transformProviders(concrete, mod)
   429  		if err := tf.Transform(g); err != nil {
   430  			t.Fatalf("err: %s", err)
   431  		}
   432  	}
   433  
   434  	expected := `module.moda.module.modb.test_object.a
   435    module.moda.provider["registry.terraform.io/hashicorp/test"]
   436  module.moda.provider["registry.terraform.io/hashicorp/test"]
   437  module.moda.test_object.a
   438    module.moda.provider["registry.terraform.io/hashicorp/test"]
   439  module.moda.test_object.x
   440    provider["registry.terraform.io/hashicorp/test"].z
   441  provider["registry.terraform.io/hashicorp/test"].z`
   442  
   443  	actual := strings.TrimSpace(g.String())
   444  	if actual != expected {
   445  		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
   446  	}
   447  }
   448  
   449  const testTransformProviderBasicStr = `
   450  aws_instance.web
   451    provider["registry.terraform.io/hashicorp/aws"]
   452  provider["registry.terraform.io/hashicorp/aws"]
   453  `
   454  
   455  const testTransformCloseProviderBasicStr = `
   456  aws_instance.web
   457    provider["registry.terraform.io/hashicorp/aws"]
   458  provider["registry.terraform.io/hashicorp/aws"]
   459  provider["registry.terraform.io/hashicorp/aws"] (close)
   460    aws_instance.web
   461    provider["registry.terraform.io/hashicorp/aws"]
   462  `
   463  
   464  const testTransformMissingProviderBasicStr = `
   465  aws_instance.web
   466    provider["registry.terraform.io/hashicorp/aws"]
   467  foo_instance.web
   468    provider["registry.terraform.io/hashicorp/foo"]
   469  provider["registry.terraform.io/hashicorp/aws"]
   470  provider["registry.terraform.io/hashicorp/aws"] (close)
   471    aws_instance.web
   472    provider["registry.terraform.io/hashicorp/aws"]
   473  provider["registry.terraform.io/hashicorp/foo"]
   474  provider["registry.terraform.io/hashicorp/foo"] (close)
   475    foo_instance.web
   476    provider["registry.terraform.io/hashicorp/foo"]
   477  `
   478  
   479  const testTransformMissingGrandchildProviderStr = `
   480  module.sub.module.subsub.bar_instance.two
   481    provider["registry.terraform.io/hashicorp/bar"]
   482  module.sub.module.subsub.foo_instance.one
   483    module.sub.provider["registry.terraform.io/hashicorp/foo"]
   484  module.sub.provider["registry.terraform.io/hashicorp/foo"]
   485  provider["registry.terraform.io/hashicorp/bar"]
   486  `
   487  
   488  const testTransformPruneProviderBasicStr = `
   489  foo_instance.web
   490    provider["registry.terraform.io/hashicorp/foo"]
   491  provider["registry.terraform.io/hashicorp/foo"]
   492  provider["registry.terraform.io/hashicorp/foo"] (close)
   493    foo_instance.web
   494    provider["registry.terraform.io/hashicorp/foo"]
   495  `
   496  
   497  const testTransformModuleProviderConfigStr = `
   498  module.child.aws_instance.thing
   499    provider["registry.terraform.io/hashicorp/aws"].foo
   500  provider["registry.terraform.io/hashicorp/aws"].foo
   501  `
   502  
   503  const testTransformModuleProviderGrandparentStr = `
   504  module.child.module.grandchild.aws_instance.baz
   505    provider["registry.terraform.io/hashicorp/aws"].foo
   506  provider["registry.terraform.io/hashicorp/aws"].foo
   507  `
   508  
   509  const testTransformImportModuleChildStr = `        
   510  module.child.aws_instance.foo
   511    provider["registry.terraform.io/hashicorp/aws"]
   512  module.child.aws_instance.foo (import id "bar")
   513    provider["registry.terraform.io/hashicorp/aws"]
   514  module.child.module.nested.aws_instance.foo
   515    provider["registry.terraform.io/hashicorp/aws"]
   516  provider["registry.terraform.io/hashicorp/aws"]`