Skip to content

Commit

Permalink
providerserver: Update to protocol versions 5.4/6.4 and enable `GetPr…
Browse files Browse the repository at this point in the history
…oviderSchemaOptional` server capability

Reference: #828
  • Loading branch information
bflad committed Aug 25, 2023
1 parent 26b488a commit fb3be76
Show file tree
Hide file tree
Showing 35 changed files with 1,973 additions and 57 deletions.
7 changes: 7 additions & 0 deletions .changes/unreleased/FEATURES-20230825-115848.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: FEATURES
body: 'providerserver: Upgrade to protocol versions 5.4 and 6.4, which can
significantly reduce memory usage with Terraform 1.6 and later when a
configuration includes multiple instances of the same provider'
time: 2023-08-25T11:58:48.820178-04:00
custom:
Issue: "828"
14 changes: 7 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.19

require (
github.com/google/go-cmp v0.5.9
github.com/hashicorp/terraform-plugin-go v0.18.0
github.com/hashicorp/terraform-plugin-go v0.18.1-0.20230824194237-31d190886564
github.com/hashicorp/terraform-plugin-log v0.9.0
)

Expand All @@ -14,7 +14,7 @@ require (
github.com/hashicorp/go-hclog v1.5.0 // indirect
github.com/hashicorp/go-plugin v1.4.10 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/terraform-registry-address v0.2.1 // indirect
github.com/hashicorp/terraform-registry-address v0.2.2 // indirect
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
Expand All @@ -23,10 +23,10 @@ require (
github.com/oklog/run v1.0.0 // indirect
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
golang.org/x/net v0.11.0 // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/text v0.10.0 // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
google.golang.org/grpc v1.56.1 // indirect
golang.org/x/net v0.13.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
google.golang.org/grpc v1.57.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
)
28 changes: 14 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ github.com/hashicorp/go-plugin v1.4.10 h1:xUbmA4jC6Dq163/fWcp8P3JuHilrHHMLNRxzGQ
github.com/hashicorp/go-plugin v1.4.10/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/terraform-plugin-go v0.18.0 h1:IwTkOS9cOW1ehLd/rG0y+u/TGLK9y6fGoBjXVUquzpE=
github.com/hashicorp/terraform-plugin-go v0.18.0/go.mod h1:l7VK+2u5Kf2y+A+742GX0ouLut3gttudmvMgN0PA74Y=
github.com/hashicorp/terraform-plugin-go v0.18.1-0.20230824194237-31d190886564 h1:INRLdX7mCAVNzcTweLg85StUa0LmaAsl8eBBboOE+r8=
github.com/hashicorp/terraform-plugin-go v0.18.1-0.20230824194237-31d190886564/go.mod h1:OLYUIu74227VwdQiU14UBqqFXac3reHV2YrWTCMAWPk=
github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
github.com/hashicorp/terraform-registry-address v0.2.1 h1:QuTf6oJ1+WSflJw6WYOHhLgwUiQ0FrROpHPYFtwTYWM=
github.com/hashicorp/terraform-registry-address v0.2.1/go.mod h1:BSE9fIFzp0qWsJUUyGquo4ldV9k2n+psif6NYkBRS3Y=
github.com/hashicorp/terraform-registry-address v0.2.2 h1:lPQBg403El8PPicg/qONZJDC6YlgCVbWDtNmmZKtBno=
github.com/hashicorp/terraform-registry-address v0.2.2/go.mod h1:LtwNbCihUoUZ3RYriyS2wF/lGPB6gF9ICLRtuDk7hSo=
github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=
github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
Expand All @@ -46,22 +46,22 @@ github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY=
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ=
google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw=
google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
Expand Down
23 changes: 23 additions & 0 deletions internal/fromproto5/getmetadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package fromproto5

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
)

// GetMetadataRequest returns the *fwserver.GetMetadataRequest
// equivalent of a *tfprotov5.GetMetadataRequest.
func GetMetadataRequest(ctx context.Context, proto5 *tfprotov5.GetMetadataRequest) *fwserver.GetMetadataRequest {
if proto5 == nil {
return nil
}

fw := &fwserver.GetMetadataRequest{}

return fw
}
46 changes: 46 additions & 0 deletions internal/fromproto5/getmetadata_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package fromproto5_test

import (
"context"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform-plugin-framework/internal/fromproto5"
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
)

func TestGetMetadataRequest(t *testing.T) {
t.Parallel()

testCases := map[string]struct {
input *tfprotov5.GetMetadataRequest
expected *fwserver.GetMetadataRequest
}{
"nil": {
input: nil,
expected: nil,
},
"empty": {
input: &tfprotov5.GetMetadataRequest{},
expected: &fwserver.GetMetadataRequest{},
},
}

for name, testCase := range testCases {
name, testCase := name, testCase

t.Run(name, func(t *testing.T) {
t.Parallel()

got := fromproto5.GetMetadataRequest(context.Background(), testCase.input)

if diff := cmp.Diff(got, testCase.expected); diff != "" {
t.Errorf("unexpected difference: %s", diff)
}
})
}
}
23 changes: 23 additions & 0 deletions internal/fromproto6/getmetadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package fromproto6

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
)

// GetMetadataRequest returns the *fwserver.GetMetadataRequest
// equivalent of a *tfprotov6.GetMetadataRequest.
func GetMetadataRequest(ctx context.Context, proto6 *tfprotov6.GetMetadataRequest) *fwserver.GetMetadataRequest {
if proto6 == nil {
return nil
}

fw := &fwserver.GetMetadataRequest{}

return fw
}
46 changes: 46 additions & 0 deletions internal/fromproto6/getmetadata_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package fromproto6_test

import (
"context"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform-plugin-framework/internal/fromproto6"
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
)

func TestGetMetadataRequest(t *testing.T) {
t.Parallel()

testCases := map[string]struct {
input *tfprotov6.GetMetadataRequest
expected *fwserver.GetMetadataRequest
}{
"nil": {
input: nil,
expected: nil,
},
"empty": {
input: &tfprotov6.GetMetadataRequest{},
expected: &fwserver.GetMetadataRequest{},
},
}

for name, testCase := range testCases {
name, testCase := name, testCase

t.Run(name, func(t *testing.T) {
t.Parallel()

got := fromproto6.GetMetadataRequest(context.Background(), testCase.input)

if diff := cmp.Diff(got, testCase.expected); diff != "" {
t.Errorf("unexpected difference: %s", diff)
}
})
}
}
32 changes: 32 additions & 0 deletions internal/fwserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,22 @@ func (s *Server) DataSourceFuncs(ctx context.Context) (map[string]func() datasou
return s.dataSourceFuncs, s.dataSourceTypesDiags
}

// DataSourceMetadatas returns a slice of DataSourceMetadata for the GetMetadata
// RPC.
func (s *Server) DataSourceMetadatas(ctx context.Context) ([]DataSourceMetadata, diag.Diagnostics) {
datasourceFuncs, diags := s.DataSourceFuncs(ctx)

datasourceMetadatas := make([]DataSourceMetadata, 0, len(datasourceFuncs))

for typeName := range datasourceFuncs {
datasourceMetadatas = append(datasourceMetadatas, DataSourceMetadata{
TypeName: typeName,
})
}

return datasourceMetadatas, diags
}

// DataSourceSchema returns the DataSource Schema for the given type name and
// caches the result for later DataSource operations.
func (s *Server) DataSourceSchema(ctx context.Context, typeName string) (fwschema.Schema, diag.Diagnostics) {
Expand Down Expand Up @@ -401,6 +417,22 @@ func (s *Server) ResourceFuncs(ctx context.Context) (map[string]func() resource.
return s.resourceFuncs, s.resourceTypesDiags
}

// ResourceMetadatas returns a slice of ResourceMetadata for the GetMetadata
// RPC.
func (s *Server) ResourceMetadatas(ctx context.Context) ([]ResourceMetadata, diag.Diagnostics) {
resourceFuncs, diags := s.ResourceFuncs(ctx)

resourceMetadatas := make([]ResourceMetadata, 0, len(resourceFuncs))

for typeName := range resourceFuncs {
resourceMetadatas = append(resourceMetadatas, ResourceMetadata{
TypeName: typeName,
})
}

return resourceMetadatas, diags
}

// ResourceSchema returns the Resource Schema for the given type name and
// caches the result for later Resource operations.
func (s *Server) ResourceSchema(ctx context.Context, typeName string) (fwschema.Schema, diag.Diagnostics) {
Expand Down
15 changes: 15 additions & 0 deletions internal/fwserver/server_capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,25 @@ package fwserver
// the toproto5 conversion logic will handle the appropriate filtering and the
// proto5server/fwserver logic will need to account for missing features.
type ServerCapabilities struct {
// GetProviderSchemaOptional signals that the provider does not require the
// GetProviderSchema RPC before other RPCs.
//
// This should always be enabled in framework providers and requires
// Terraform 1.6 or later.
GetProviderSchemaOptional bool

// PlanDestroy signals that the provider is ready for the
// PlanResourceChange RPC on resource destruction.
//
// This should always be enabled in framework providers and requires
// Terraform 1.3 or later.
PlanDestroy bool
}

// ServerCapabilities returns the server capabilities.
func (s *Server) ServerCapabilities() *ServerCapabilities {
return &ServerCapabilities{
GetProviderSchemaOptional: true,
PlanDestroy: true,
}
}
70 changes: 70 additions & 0 deletions internal/fwserver/server_getmetadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package fwserver

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/logging"
"github.com/hashicorp/terraform-plugin-framework/provider"
)

// GetMetadataRequest is the framework server request for the
// GetMetadata RPC.
type GetMetadataRequest struct{}

// GetMetadataResponse is the framework server response for the
// GetMetadata RPC.
type GetMetadataResponse struct {
DataSources []DataSourceMetadata
Diagnostics diag.Diagnostics
Resources []ResourceMetadata
ServerCapabilities *ServerCapabilities
}

// DataSourceMetadata is the framework server equivalent of the
// tfprotov5.DataSourceMetadata and tfprotov6.DataSourceMetadata types.
type DataSourceMetadata struct {
// TypeName is the name of the data resource.
TypeName string
}

// ResourceMetadata is the framework server equivalent of the
// tfprotov5.ResourceMetadata and tfprotov6.ResourceMetadata types.
type ResourceMetadata struct {
// TypeName is the name of the managed resource.
TypeName string
}

// GetMetadata implements the framework server GetMetadata RPC.
func (s *Server) GetMetadata(ctx context.Context, req *GetMetadataRequest, resp *GetMetadataResponse) {
resp.DataSources = []DataSourceMetadata{}
resp.Resources = []ResourceMetadata{}
resp.ServerCapabilities = s.ServerCapabilities()

metadataReq := provider.MetadataRequest{}
metadataResp := provider.MetadataResponse{}

logging.FrameworkTrace(ctx, "Calling provider defined Provider Metadata")
s.Provider.Metadata(ctx, metadataReq, &metadataResp)
logging.FrameworkTrace(ctx, "Called provider defined Provider Metadata")

s.providerTypeName = metadataResp.TypeName

datasourceMetadatas, diags := s.DataSourceMetadatas(ctx)

resp.Diagnostics.Append(diags...)

resourceMetadatas, diags := s.ResourceMetadatas(ctx)

resp.Diagnostics.Append(diags...)

if resp.Diagnostics.HasError() {
return
}

resp.DataSources = datasourceMetadatas
resp.Resources = resourceMetadatas
}
Loading

0 comments on commit fb3be76

Please sign in to comment.