Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ require (
github.com/hashicorp/hcl v1.0.0
github.com/hashicorp/hcl/v2 v2.24.0
github.com/hashicorp/hil v0.0.0-20190212132231-97b3a9cdfa93
github.com/hashicorp/terraform-plugin-framework v1.15.0
github.com/hashicorp/terraform-plugin-framework v1.16.1
github.com/hashicorp/terraform-plugin-framework-validators v0.17.0
github.com/hashicorp/terraform-plugin-mux v0.20.0
github.com/hashicorp/terraform-plugin-sdk v1.7.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2049,8 +2049,8 @@ github.com/hashicorp/terraform-exec v0.24.0/go.mod h1:lluc/rDYfAhYdslLJQg3J0oDqo
github.com/hashicorp/terraform-json v0.4.0/go.mod h1:eAbqb4w0pSlRmdvl8fOyHAi/+8jnkVYN28gJkSJrLhU=
github.com/hashicorp/terraform-json v0.27.1 h1:zWhEracxJW6lcjt/JvximOYyc12pS/gaKSy/wzzE7nY=
github.com/hashicorp/terraform-json v0.27.1/go.mod h1:GzPLJ1PLdUG5xL6xn1OXWIjteQRT2CNT9o/6A9mi9hE=
github.com/hashicorp/terraform-plugin-framework v1.15.0 h1:LQ2rsOfmDLxcn5EeIwdXFtr03FVsNktbbBci8cOKdb4=
github.com/hashicorp/terraform-plugin-framework v1.15.0/go.mod h1:hxrNI/GY32KPISpWqlCoTLM9JZsGH3CyYlir09bD/fI=
github.com/hashicorp/terraform-plugin-framework v1.16.1 h1:1+zwFm3MEqd/0K3YBB2v9u9DtyYHyEuhVOfeIXbteWA=
github.com/hashicorp/terraform-plugin-framework v1.16.1/go.mod h1:0xFOxLy5lRzDTayc4dzK/FakIgBhNf/lC4499R9cV4Y=
github.com/hashicorp/terraform-plugin-framework-validators v0.17.0 h1:0uYQcqqgW3BMyyve07WJgpKorXST3zkpzvrOnf3mpbg=
github.com/hashicorp/terraform-plugin-framework-validators v0.17.0/go.mod h1:VwdfgE/5Zxm43flraNa0VjcvKQOGVrcO4X8peIri0T0=
github.com/hashicorp/terraform-plugin-go v0.29.0 h1:1nXKl/nSpaYIUBU1IG/EsDOX0vv+9JxAltQyDMpq5mU=
Expand Down
2 changes: 2 additions & 0 deletions pkg/convert/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ type Encoding interface {
NewResourceEncoder(resource string, resourceType tftypes.Object) (Encoder, error)
NewDataSourceDecoder(dataSource string, dataSourceType tftypes.Object) (Decoder, error)
NewDataSourceEncoder(dataSource string, dataSourceType tftypes.Object) (Encoder, error)
NewListResourceEncoder(listResource string, listResourceType tftypes.Object) (Encoder, error)
NewListResourceDecoder(listResource string, listResourceType tftypes.Object) (Decoder, error)
}

// Like PropertyNames but specialized to either a type by token or config property.
Expand Down
22 changes: 22 additions & 0 deletions pkg/convert/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,28 @@ func (e *encoding) NewDataSourceDecoder(
return dec, nil
}

func (e *encoding) NewListResourceEncoder(
listResource string, objectType tftypes.Object,
) (Encoder, error) {
mctx := newListResourceSchemaMapContext(listResource, e.SchemaOnlyProvider, e.ProviderInfo)
enc, err := NewObjectEncoder(ObjectSchema{mctx.schemaMap, mctx.schemaInfos, &objectType})
if err != nil {
return nil, fmt.Errorf("cannot derive an encoder for list resource %q: %w", listResource, err)
}
return enc, nil
}

func (e *encoding) NewListResourceDecoder(
listResource string, objectType tftypes.Object,
) (Decoder, error) {
mctx := newListResourceSchemaMapContext(listResource, e.SchemaOnlyProvider, e.ProviderInfo)
dec, err := NewObjectDecoder(ObjectSchema{mctx.schemaMap, mctx.schemaInfos, &objectType})
if err != nil {
return nil, fmt.Errorf("cannot derive an decoder for list resource %q: %w", listResource, err)
}
return dec, nil
}

func buildPropertyEncoders(
mctx *schemaMapContext, objectType tftypes.Object,
) (map[terraformPropertyName]Encoder, error) {
Expand Down
17 changes: 16 additions & 1 deletion pkg/convert/schema_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"

"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfbridge"
"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim"
shim "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim"
"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim/walk"
)

Expand Down Expand Up @@ -73,6 +73,21 @@ func newDataSourceSchemaMapContext(
return newSchemaMapContext(sm, fields)
}

func newListResourceSchemaMapContext(
listResource string,
schemaOnlyProvider shim.Provider,
providerInfo *tfbridge.ProviderInfo,
) *schemaMapContext {
r := schemaOnlyProvider.ListResourcesMap().Get(listResource)
contract.Assertf(r != nil, "no list resource %q found in ListResourcesMap", listResource)
sm := r.Schema()
var fields map[string]*tfbridge.SchemaInfo
if providerInfo != nil {
fields = providerInfo.ListResources[listResource].GetFields()
}
return newSchemaMapContext(sm, fields)
}

func (sc *schemaMapContext) PropertyKey(tfname terraformPropertyName, _ tftypes.Type) resource.PropertyKey {
return sc.ToPropertyKey(tfname)
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/pf/internal/pfutils/attr.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

"github.com/hashicorp/terraform-plugin-framework/attr"
dschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
lrschema "github.com/hashicorp/terraform-plugin-framework/list/schema"
prschema "github.com/hashicorp/terraform-plugin-framework/provider/schema"
rschema "github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-go/tftypes"
Expand Down Expand Up @@ -65,6 +66,10 @@ func FromResourceAttribute(x rschema.Attribute) Attr {
return FromAttrLike(x)
}

func FromListResourceAttribute(x lrschema.Attribute) Attr {
return FromAttrLike(x)
}

func FromAttrLike(attrLike AttrLike) Attr {
nested, nestingMode := extractNestedAttributes(attrLike)
hasDefault := hasDefault(attrLike)
Expand Down
5 changes: 5 additions & 0 deletions pkg/pf/internal/pfutils/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

"github.com/hashicorp/terraform-plugin-framework/attr"
dschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
lrschema "github.com/hashicorp/terraform-plugin-framework/list/schema"
prschema "github.com/hashicorp/terraform-plugin-framework/provider/schema"
rschema "github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
Expand Down Expand Up @@ -58,6 +59,10 @@ func FromResourceBlock(x rschema.Block) Block {
return FromBlockLike(x)
}

func FromListResourceBlock(x lrschema.Block) Block {
return FromBlockLike(x)
}

func FromBlockLike(x BlockLike) Block {
minItems, maxItems, _ := detectSizeConstraints(x)
attrs, blocks, mode := extractBlockNesting(x)
Expand Down
74 changes: 74 additions & 0 deletions pkg/pf/internal/pfutils/listresources.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// 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.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package pfutils

import (
"context"
"fmt"

listres "github.com/hashicorp/terraform-plugin-framework/list"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/resource"

"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/internal/runtypes"
shim "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim"
)

func GatherListResources[F func(Schema) shim.SchemaMap](
ctx context.Context, prov provider.Provider, f F,
) (runtypes.ListResources, error) {
provMetadata := queryProviderMetadata(ctx, prov)
lr := make(collection[func() listres.ListResource])
lp, ok := prov.(provider.ProviderWithListResources)
if !ok {
return &listResources{collection: lr, convert: f}, nil
}

for _, makeListResource := range lp.ListResources(ctx) {
listResource := makeListResource()

meta := resource.MetadataResponse{}
listResource.Metadata(ctx, resource.MetadataRequest{
ProviderTypeName: provMetadata.TypeName,
}, &meta)

schemaResponse := &listres.ListResourceSchemaResponse{}
listResource.ListResourceConfigSchema(ctx, listres.ListResourceSchemaRequest{}, schemaResponse)

if err := checkDiagsForErrors(schemaResponse.Diagnostics); err != nil {
return nil, fmt.Errorf("ListResource %s GetSchema() error: %w", meta.TypeName, err)
}

lr[runtypes.TypeOrRenamedEntityName(meta.TypeName)] = entry[func() listres.ListResource]{
t: makeListResource,
schema: FromListResourceSchema(schemaResponse.Schema),
tfName: runtypes.TypeName(meta.TypeName),
}
}

return &listResources{collection: lr, convert: f}, nil
}

type listResources struct {
collection[func() listres.ListResource]
convert func(Schema) shim.SchemaMap
}

func (r listResources) Schema(t runtypes.TypeOrRenamedEntityName) runtypes.Schema {
entry := r.collection[t]
return runtypesSchemaAdapter{entry.schema, r.convert, entry.tfName}
}

func (listResources) IsListResources() {}
7 changes: 7 additions & 0 deletions pkg/pf/internal/pfutils/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

"github.com/hashicorp/terraform-plugin-framework/attr"
dschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
lrschema "github.com/hashicorp/terraform-plugin-framework/list/schema"
prschema "github.com/hashicorp/terraform-plugin-framework/provider/schema"
rschema "github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
Expand Down Expand Up @@ -66,6 +67,12 @@ func FromResourceSchema(x rschema.Schema) Schema {
return newSchemaAdapter(x, x.Type(), x.DeprecationMessage, attrs, blocks, &x)
}

func FromListResourceSchema(x lrschema.Schema) Schema {
attrs := convertMap(FromListResourceAttribute, x.Attributes)
blocks := convertMap(FromListResourceBlock, x.Blocks)
return newSchemaAdapter(x, x.Type(), x.DeprecationMessage, attrs, blocks, nil)
}

type schemaAdapter struct {
tftypes.AttributePathStepper
attrType attr.Type
Expand Down
5 changes: 5 additions & 0 deletions pkg/pf/internal/runtypes/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,8 @@ type DataSources interface {
collection
IsDataSources()
}

type ListResources interface {
collection
IsListResources()
}
90 changes: 90 additions & 0 deletions pkg/pf/internal/schemashim/list_resource_map.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// 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.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package schemashim

import (
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"

"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/internal/internalinter"
"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/internal/runtypes"
shim "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim"
)

// Resource map needs to support Set (mutability) for RenameResourceWithAlias.
func newSchemaOnlyListResourceMap(resources runtypes.ListResources) schemaOnlyListResourceMap {
m := schemaOnlyListResourceMap{Map: make(map[string]*schemaOnlyListResource)}
for _, name := range resources.All() {
key := string(name)
v := resources.Schema(name)
m.Map[key] = &schemaOnlyListResource{v, internalinter.Internal{}}
}
return m
}

type schemaOnlyListResourceMap struct {
internalinter.Internal
Map map[string]*schemaOnlyListResource
}

var (
_ shim.ResourceMap = schemaOnlyListResourceMap{}
_ runtypes.ListResources = schemaOnlyListResourceMap{}
)

func (m schemaOnlyListResourceMap) Len() int {
return len(m.Map)
}

func (m schemaOnlyListResourceMap) Get(key string) shim.Resource {
return m.Map[key]
}

func (m schemaOnlyListResourceMap) GetOk(key string) (shim.Resource, bool) {
v, ok := m.Map[key]
return v, ok
}

func (m schemaOnlyListResourceMap) Range(each func(key string, value shim.Resource) bool) {
for k, v := range m.Map {
if !each(k, v) {
return
}
}
}

func (m schemaOnlyListResourceMap) Set(key string, value shim.Resource) {
v, ok := value.(*schemaOnlyListResource)
contract.Assertf(ok, "Set must be a %T, found a %T", v, value)
m.Map[key] = v
}

func (m schemaOnlyListResourceMap) All() []runtypes.TypeOrRenamedEntityName {
arr := make([]runtypes.TypeOrRenamedEntityName, 0, len(m.Map))
for k := range m.Map {
arr = append(arr, runtypes.TypeOrRenamedEntityName(k))
}
return arr
}

func (m schemaOnlyListResourceMap) Has(key runtypes.TypeOrRenamedEntityName) bool {
_, ok := m.Map[string(key)]
return ok
}

func (m schemaOnlyListResourceMap) Schema(key runtypes.TypeOrRenamedEntityName) runtypes.Schema {
return m.Map[string(key)].tf
}

func (m schemaOnlyListResourceMap) IsListResources() {}
71 changes: 71 additions & 0 deletions pkg/pf/internal/schemashim/listresource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// 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.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package schemashim

import (
"context"

"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"

"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/internal/internalinter"
"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/internal/runtypes"
shim "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim"
"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/valueshim"
)

type schemaOnlyListResource struct {
tf runtypes.Schema
internalinter.Internal
}

var _ shim.Resource = (*schemaOnlyListResource)(nil)

func (r *schemaOnlyListResource) SchemaType() valueshim.Type {
protoSchema, err := r.tf.ResourceProtoSchema(context.Background())
contract.AssertNoErrorf(err, "ResourceProtoSchema failed")
return valueshim.FromTType(protoSchema.ValueType())
}

func (r *schemaOnlyListResource) Schema() shim.SchemaMap {
return r.tf.Shim()
}

func (r *schemaOnlyListResource) SchemaVersion() int {
panic("list resources do not have schema versions")
}

func (r *schemaOnlyListResource) DeprecationMessage() string {
return r.tf.DeprecationMessage()
}

func (*schemaOnlyListResource) Importer() shim.ImportFunc {
panic("schemaOnlyListResource does not implement runtime operation ImporterFunc")
}

func (*schemaOnlyListResource) Timeouts() *shim.ResourceTimeout {
panic("schemaOnlyListResource does not implement runtime operation Timeouts")
}

func (*schemaOnlyListResource) InstanceState(id string, object,
meta map[string]interface{},
) (shim.InstanceState, error) {
panic("schemaOnlyListResource does not implement runtime operation InstanceState")
}

func (*schemaOnlyListResource) DecodeTimeouts(
config shim.ResourceConfig,
) (*shim.ResourceTimeout, error) {
panic("schemaOnlyListResource does not implement runtime operation DecodeTimeouts")
}
Loading
Loading