Skip to content

Commit

Permalink
Merge f94fa8d into 56d0534
Browse files Browse the repository at this point in the history
  • Loading branch information
Frassle committed Dec 16, 2022
2 parents 56d0534 + f94fa8d commit ad6a5d6
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 3 deletions.
15 changes: 14 additions & 1 deletion pkg/tf2pulumi/convert/eject.go
Expand Up @@ -84,6 +84,13 @@ func (o EjectOptions) logf(format string, arguments ...interface{}) {

// Eject converts a Terraform module at the provided location into a Pulumi module.
func Eject(dir string, loader schema.ReferenceLoader, mapper convert.Mapper) (*workspace.Project, *pcl.Program, error) {
return ejectWithOpts(dir, loader, mapper, nil)
}

// Used for testing so we can check eject with partial options set works.
func ejectWithOpts(dir string, loader schema.ReferenceLoader, mapper convert.Mapper,
setOpts func(*EjectOptions)) (*workspace.Project, *pcl.Program, error) {

if loader == nil {
panic("must provide a non-nil loader")
}
Expand All @@ -93,6 +100,9 @@ func Eject(dir string, loader schema.ReferenceLoader, mapper convert.Mapper) (*w
Loader: loader,
ProviderInfoSource: il.NewMapperProviderInfoSource(mapper),
}
if setOpts != nil {
setOpts(&opts)
}

tfFiles, program, diags, err := internalEject(opts)

Expand All @@ -104,9 +114,12 @@ func Eject(dir string, loader schema.ReferenceLoader, mapper convert.Mapper) (*w
return nil, nil, err
}
}
if err != nil || diags.HasErrors() {
if err != nil {
return nil, nil, fmt.Errorf("failed to load Terraform configuration, %v", err)
}
if diags.HasErrors() {
return nil, nil, fmt.Errorf("failed to load Terraform configuration, %v", diags)
}

project := &workspace.Project{
Name: tokens.PackageName(filepath.Base(dir)),
Expand Down
16 changes: 14 additions & 2 deletions pkg/tf2pulumi/convert/eject_test.go
@@ -1,4 +1,4 @@
// Copyright 2016-2018, Pulumi Corporation.
// Copyright 2016-2022, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -112,7 +112,19 @@ func TestEject(t *testing.T) {
hclPath := tt.path
pclPath := filepath.Join(tt.path, "pcl")

project, program, err := Eject(hclPath, loader, mapper)
// If this is a partial test turn on the options to allow missing bits
partial := strings.HasPrefix(tt.name, "partial_")
var setOpts func(*EjectOptions)
if partial {
setOpts = func(opts *EjectOptions) {
opts.SkipResourceTypechecking = true
opts.AllowMissingProperties = true
opts.AllowMissingVariables = true
opts.FilterResourceNames = true
}
}

project, program, err := ejectWithOpts(hclPath, loader, mapper, setOpts)
require.NoError(t, err)
// Assert the project name is as expected (the directory name)
assert.Equal(t, tokens.PackageName(tt.name), project.Name)
Expand Down
22 changes: 22 additions & 0 deletions pkg/tf2pulumi/convert/testdata/expressions/main.tf
Expand Up @@ -29,6 +29,16 @@ locals {
a_key = "hello"
a_value = -1
a_list = [1, 2, 3]
a_list_of_maps = [
{
x: [1, 2]
y: [3, 4]
},
{
x: [5, 6]
y: [7, 8]
}
]
}

output "static_index_out" {
Expand All @@ -55,6 +65,10 @@ output "complex_object_out" {
}
}

output "simple_template" {
value = "${local.a_value}"
}

output "quoted_template" {
value = "The key is ${local.a_key}"
}
Expand All @@ -76,4 +90,12 @@ output "for_tuple_value_only" {

output "for_object" {
value = {for key, value in ["a", "b"] : key => "${value}:${local.a_value}" if key != 0}
}

output "relative_traversal_attr" {
value = local.a_list_of_maps[0].x
}

output "relative_traversal_index" {
value = local.a_list_of_maps[0]["x"]
}
19 changes: 19 additions & 0 deletions pkg/tf2pulumi/convert/testdata/expressions/pcl/main.pp
Expand Up @@ -22,6 +22,16 @@
aKey = "hello"
aValue = -1
aList = [1, 2, 3]
aListOfMaps = [
{
x: [1, 2]
y: [3, 4]
},
{
x: [5, 6]
y: [7, 8]
}
]
output staticIndexOut {
value = aList[1]
}
Expand All @@ -43,6 +53,9 @@
}
}
}
output simpleTemplate {
value = aValue
}
output quotedTemplate {
value = "The key is ${aKey}"
}
Expand All @@ -60,4 +73,10 @@
}
output forObject {
value = {for key, value in ["a", "b"] : key => "${value}:${aValue}" if key != 0}
}
output relativeTraversalAttr {
value = aListOfMaps[0].x
}
output relativeTraversalIndex {
value = aListOfMaps[0]["x"]
}
@@ -0,0 +1,4 @@
resource "simple_resource" "example" {
input_one = data.some_data_source.example.attr
input_two = some_resource_type.example.list[0]
}
@@ -0,0 +1,4 @@
resource example "simple:index:resource" {
inputOne = data.some_data_source.example.attr
inputTwo = some_resource_type.example.list[0]
}
@@ -0,0 +1,13 @@
data "simple_data_source" "example" {
input_one = "hello"
input_two = true
}

resource "simple_resource" "example" {
input_one = data.simple_data_source.example.input_one
input_two = data.simple_data_source.example.input_two
}

output "example" {
value = simple_resource.example.result
}
@@ -0,0 +1,11 @@
exampledata_source = invoke("simple:index:data_source", {
inputOne = "hello",
inputTwo = true
})
resource exampleresource "simple:index:resource" {
inputOne = exampledata_source.inputOne
inputTwo = exampledata_source.inputTwo
}
output example {
value = exampleresource.result
}
22 changes: 22 additions & 0 deletions pkg/tf2pulumi/convert/testdata/splat/main.tf
@@ -0,0 +1,22 @@
resource "simple_resource" "a_resource_with_count" {
count = 4
input_one = "Hello ${count.index}"
input_two = true
}

output "some_output_a" {
value = simple_resource.a_resource_with_count[*].result
}

resource "simple_resource" "a_resource_with_foreach_map" {
for_each = {
cruel: "world"
good: "class"
}
input_one = "Hello ${each.key} ${each.value}"
input_two = 0
}

output "some_output_b" {
value = simple_resource.a_resource_with_foreach_map[*].result
}
27 changes: 27 additions & 0 deletions pkg/tf2pulumi/convert/testdata/splat/pcl/main.pp
@@ -0,0 +1,27 @@
resource aResourceWithCount "simple:index:resource" {
options {
range = 4

}
inputOne = "Hello ${range.value}"
inputTwo = true
}
output someOutputA {
value = aResourceWithCount[*].result

}
resource aResourceWithForeachMap "simple:index:resource" {
options {
range = {
cruel: "world"
good: "class"
}

}
inputOne = "Hello ${range.key} ${range.value}"
inputTwo = 0
}
output someOutputB {
value = aResourceWithForeachMap[*].result

}

0 comments on commit ad6a5d6

Please sign in to comment.