Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use OpenTofu planner with Plugin Framework providers #2188

Merged
merged 31 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
081d57b
Toward removing custom objchange implementation
t0yv0 Jul 16, 2024
485fd18
Vendor files for parsing schema blocks from proto
t0yv0 Jul 16, 2024
4bdf139
Tidy code-generation
t0yv0 Jul 16, 2024
34b9e26
Vendor tfprotov6/toproto code
t0yv0 Jul 16, 2024
df689b5
Fill out convertBlock
t0yv0 Jul 16, 2024
758aa9a
Fill in the missing tfprotov6.Schema conversions
t0yv0 Jul 24, 2024
3828837
Vendor and rebuild tfplugin6 protos
t0yv0 Jul 24, 2024
c064bd4
Clean up pkg/opentofu vendored code
t0yv0 Jul 24, 2024
f14431b
Clean up tfprotov6 vendored code
t0yv0 Jul 24, 2024
351e4e8
Simplify proposed_new conversions
t0yv0 Jul 24, 2024
673a096
Disambiguate the protos further
t0yv0 Jul 24, 2024
24042b6
Actually fix the proto conflict
t0yv0 Jul 24, 2024
028127e
Fix test cases that had invalid schemata
t0yv0 Jul 24, 2024
15dbda0
Lint corrections
t0yv0 Jul 24, 2024
f395b51
Rerun opentofu go generate
t0yv0 Jul 25, 2024
4fbd1d7
Lint auto-fixes
t0yv0 Jul 25, 2024
f8f08e9
Exclude vendored code from the linter (terraform-plugin-go)
t0yv0 Jul 25, 2024
3f8da61
Bring back nestingmode_string.go
t0yv0 Jul 25, 2024
f72c432
golangci-lint run --fix
t0yv0 Jul 25, 2024
4007cff
Explain changes to test expectations.
t0yv0 Jul 25, 2024
9d03fe8
Accept set reordering
t0yv0 Jul 25, 2024
5bf30d0
Another instance of newly introduced set reordering
t0yv0 Jul 25, 2024
63ba4ac
Fix TestPrimitiveTypes/diff(some).golden
t0yv0 Jul 25, 2024
7dea5df
Move tfplugin6 under vendored
t0yv0 Jul 25, 2024
89eac4c
Move to vendored/tfplugin6
t0yv0 Jul 25, 2024
b26ab85
Adjust references
t0yv0 Jul 25, 2024
ffbd78d
Move more vendored code
t0yv0 Jul 25, 2024
c200e72
Fix compilation
t0yv0 Jul 25, 2024
457e48a
Fix PF compilation
t0yv0 Jul 25, 2024
1574963
README.md
t0yv0 Jul 25, 2024
3f907fb
Adjust linter settings
t0yv0 Jul 25, 2024
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
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ issues:
- pkg/tf2pulumi/internal/addrs
- pkg/tf2pulumi/internal/config
- pkg/tf2pulumi/internal/configs
- pkg/vendored
linters-settings:
gci:
sections:
Expand Down
1 change: 1 addition & 0 deletions dynamic/testdata/TestPrimitiveTypes/diff(some).golden
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"changes": "DIFF_SOME",
"diffs": [
"attrNumberComputed",
"attrNumberRequired",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a correct result, this used to be a bug. Likely a degenerate case because a required property cannot be not specified in the program.

"attrStringDefault",
"attrStringDefaultOverridden",
"attrStringRequired"
Expand Down
2 changes: 1 addition & 1 deletion pf/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ require (
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/zclconf/go-cty v1.14.2 // indirect
github.com/zclconf/go-cty v1.14.2
go.opencensus.io v0.24.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
gocloud.dev v0.37.0 // indirect
Expand Down
119 changes: 119 additions & 0 deletions pf/internal/pfutils/convert_rschema_to_proto.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// Copyright 2016-2024, 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"
"errors"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/hashicorp/terraform-plugin-framework/resource"
rschema "github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
)

// Assist converting Plugin framework schemata to proto schemata for a resource.
func convertResourceSchemaToProto(ctx context.Context, s *rschema.Schema) (*tfprotov6.Schema, error) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a slightly convoluted way to convert rschema.Schema to protos. Perhaps could be avoided by vendoring internal code from the Plugin framework.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is indeed quite roundabout - could we add a comment with a TODO here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I don't intend revisiting though, I think alternatives are worse.

p := &singleResourceProvider{s}

mk := providerserver.NewProtocol6WithError(p)
srv, err := mk()
if err != nil {
return nil, err
}
resp, err := srv.GetProviderSchema(ctx, &tfprotov6.GetProviderSchemaRequest{})
if err != nil {
return nil, err
}
var diagErrors []error
for _, d := range resp.Diagnostics {
if d.Severity == tfprotov6.DiagnosticSeverityError {
diagErrors = append(diagErrors, d.Attribute.NewErrorf("%s\n%s", d.Summary, d.Detail))
}
}
if err := errors.Join(diagErrors...); err != nil {
return nil, err
}
for _, r := range resp.ResourceSchemas {
return r, nil
}
return nil, fmt.Errorf("GetProviderSchema did not return any resource schemas")
}

type singleResourceProvider struct {
resourceSchema *rschema.Schema
}

var _ provider.Provider = &singleResourceProvider{}

func (srp singleResourceProvider) Metadata(
ctx context.Context,
req provider.MetadataRequest,
resp *provider.MetadataResponse,
) {
resp.TypeName = "p"
}

func (srp singleResourceProvider) Schema(context.Context, provider.SchemaRequest, *provider.SchemaResponse) {
}

func (srp singleResourceProvider) Configure(context.Context, provider.ConfigureRequest, *provider.ConfigureResponse) {
}

func (srp singleResourceProvider) DataSources(context.Context) []func() datasource.DataSource {
return nil
}

func (srp singleResourceProvider) Resources(context.Context) []func() resource.Resource {
mk := func() resource.Resource {
return &schemaOnlyResource{srp.resourceSchema}
}
return []func() resource.Resource{mk}
}

type schemaOnlyResource struct {
schema *rschema.Schema
}

var _ resource.Resource = &schemaOnlyResource{}

func (r *schemaOnlyResource) Metadata(
ctx context.Context,
req resource.MetadataRequest,
resp *resource.MetadataResponse,
) {
resp.TypeName = "r"
}

func (r *schemaOnlyResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
if r.schema != nil {
resp.Schema = *r.schema
}
}

func (r *schemaOnlyResource) Create(context.Context, resource.CreateRequest, *resource.CreateResponse) {
}

func (r *schemaOnlyResource) Read(context.Context, resource.ReadRequest, *resource.ReadResponse) {
}

func (r *schemaOnlyResource) Update(context.Context, resource.UpdateRequest, *resource.UpdateResponse) {
}

func (r *schemaOnlyResource) Delete(context.Context, resource.DeleteRequest, *resource.DeleteResponse) {
}
Loading