Skip to content

Commit 2f29333

Browse files
committed
Allow tracking gRPC calls to the upstream provider
1 parent 5c84af8 commit 2f29333

File tree

5 files changed

+143
-81
lines changed

5 files changed

+143
-81
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright 2016-2024, Pulumi Corporation.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package grpcutil
16+
17+
import (
18+
"context"
19+
"encoding/json"
20+
"fmt"
21+
"os"
22+
"runtime"
23+
"sync"
24+
25+
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
26+
"google.golang.org/grpc"
27+
)
28+
29+
var (
30+
pulumiTFDebugGRPCLogs = os.Getenv("PULUMI_TF_DEBUG_GRPC")
31+
grpcLogLock sync.Mutex
32+
grpcLogFileTarget *os.File
33+
)
34+
35+
type grpcLog struct {
36+
Call string `json:"call"`
37+
Request string `json:"request"`
38+
Response string `json:"response"`
39+
Error []string `json:"error,omitempty"`
40+
}
41+
42+
func writeGRPCLog(log grpcLog) error {
43+
if pulumiTFDebugGRPCLogs == "" {
44+
return nil
45+
}
46+
grpcLogLock.Lock()
47+
defer grpcLogLock.Unlock()
48+
49+
if grpcLogFileTarget == nil {
50+
var err error
51+
grpcLogFileTarget, err = os.Create(pulumiTFDebugGRPCLogs)
52+
if err != nil {
53+
return err
54+
}
55+
}
56+
57+
b, err := json.Marshal(log)
58+
contract.AssertNoErrorf(err, "%T should always marshal", log)
59+
_, err = grpcLogFileTarget.Write(append(b, '\n'))
60+
if err != nil {
61+
return err
62+
}
63+
return grpcLogFileTarget.Sync()
64+
}
65+
66+
func Translate[
67+
In, Out fmt.Stringer,
68+
Final any,
69+
Call func(context.Context, In, ...grpc.CallOption) (Out, error),
70+
MapResult func(Out) Final,
71+
](
72+
ctx context.Context,
73+
call Call,
74+
i In,
75+
m MapResult,
76+
) (_ Final, err error) {
77+
var log grpcLog
78+
if pulumiTFDebugGRPCLogs != "" {
79+
log.Request = i.String()
80+
if _, line, num, ok := runtime.Caller(2); ok {
81+
log.Call = fmt.Sprintf("%s:%d", line, num)
82+
}
83+
defer func() {
84+
e := writeGRPCLog(log)
85+
if err == nil {
86+
err = e
87+
}
88+
}()
89+
}
90+
v, err := call(ctx, i)
91+
if err != nil {
92+
var tmp Final
93+
log.Error = []string{err.Error()}
94+
return tmp, err
95+
}
96+
if pulumiTFDebugGRPCLogs != "" {
97+
log.Response = v.String()
98+
}
99+
return m(v), nil
100+
}

dynamic/internal/shim/protov5/provider.go

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ import (
2424

2525
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
2626
"github.com/opentofu/opentofu/internal/tfplugin5"
27+
"github.com/opentofu/opentofu/shim/grpcutil"
2728
"github.com/opentofu/opentofu/shim/protov5/translate"
28-
"google.golang.org/grpc"
2929
)
3030

3131
var _ tfprotov5.ProviderServer = (*provider)(nil)
@@ -39,7 +39,7 @@ type provider struct{ remote tfplugin5.ProviderClient }
3939
func (p provider) GetMetadata(
4040
ctx context.Context, req *tfprotov5.GetMetadataRequest,
4141
) (*tfprotov5.GetMetadataResponse, error) {
42-
return translateGRPC(ctx,
42+
return grpcutil.Translate(ctx,
4343
p.remote.GetMetadata,
4444
translate.GetMetadataRequest(req),
4545
translate.GetMetadataResponse)
@@ -48,7 +48,7 @@ func (p provider) GetMetadata(
4848
func (p provider) GetProviderSchema(
4949
ctx context.Context, req *tfprotov5.GetProviderSchemaRequest,
5050
) (*tfprotov5.GetProviderSchemaResponse, error) {
51-
return translateGRPC(ctx,
51+
return grpcutil.Translate(ctx,
5252
p.remote.GetSchema,
5353
translate.GetProviderSchemaRequest(req),
5454
translate.GetProviderSchemaResponse)
@@ -57,7 +57,7 @@ func (p provider) GetProviderSchema(
5757
func (p provider) PrepareProviderConfig(
5858
ctx context.Context, req *tfprotov5.PrepareProviderConfigRequest,
5959
) (*tfprotov5.PrepareProviderConfigResponse, error) {
60-
return translateGRPC(ctx,
60+
return grpcutil.Translate(ctx,
6161
p.remote.PrepareProviderConfig,
6262
translate.PrepareProviderConfigRequest(req),
6363
translate.PrepareProviderConfigResponse)
@@ -66,7 +66,7 @@ func (p provider) PrepareProviderConfig(
6666
func (p provider) ConfigureProvider(
6767
ctx context.Context, req *tfprotov5.ConfigureProviderRequest,
6868
) (*tfprotov5.ConfigureProviderResponse, error) {
69-
return translateGRPC(ctx,
69+
return grpcutil.Translate(ctx,
7070
p.remote.Configure,
7171
translate.ConfigureProviderRequest(req),
7272
translate.ConfigureProviderResponse)
@@ -75,7 +75,7 @@ func (p provider) ConfigureProvider(
7575
func (p provider) StopProvider(
7676
ctx context.Context, req *tfprotov5.StopProviderRequest,
7777
) (*tfprotov5.StopProviderResponse, error) {
78-
return translateGRPC(ctx,
78+
return grpcutil.Translate(ctx,
7979
p.remote.Stop,
8080
translate.StopProviderRequest(req),
8181
translate.StopProviderResponse)
@@ -84,7 +84,7 @@ func (p provider) StopProvider(
8484
func (p provider) ValidateResourceTypeConfig(
8585
ctx context.Context, req *tfprotov5.ValidateResourceTypeConfigRequest,
8686
) (*tfprotov5.ValidateResourceTypeConfigResponse, error) {
87-
return translateGRPC(ctx,
87+
return grpcutil.Translate(ctx,
8888
p.remote.ValidateResourceTypeConfig,
8989
translate.ValidateResourceTypeConfigRequest(req),
9090
translate.ValidateResourceTypeConfigResponse)
@@ -93,7 +93,7 @@ func (p provider) ValidateResourceTypeConfig(
9393
func (p provider) UpgradeResourceState(
9494
ctx context.Context, req *tfprotov5.UpgradeResourceStateRequest,
9595
) (*tfprotov5.UpgradeResourceStateResponse, error) {
96-
return translateGRPC(ctx,
96+
return grpcutil.Translate(ctx,
9797
p.remote.UpgradeResourceState,
9898
translate.UpgradeResourceStateRequest(req),
9999
translate.UpgradeResourceStateResponse)
@@ -102,7 +102,7 @@ func (p provider) UpgradeResourceState(
102102
func (p provider) ReadResource(
103103
ctx context.Context, req *tfprotov5.ReadResourceRequest,
104104
) (*tfprotov5.ReadResourceResponse, error) {
105-
return translateGRPC(ctx,
105+
return grpcutil.Translate(ctx,
106106
p.remote.ReadResource,
107107
translate.ReadResourceRequest(req),
108108
translate.ReadResourceResponse)
@@ -111,7 +111,7 @@ func (p provider) ReadResource(
111111
func (p provider) PlanResourceChange(
112112
ctx context.Context, req *tfprotov5.PlanResourceChangeRequest,
113113
) (*tfprotov5.PlanResourceChangeResponse, error) {
114-
return translateGRPC(ctx,
114+
return grpcutil.Translate(ctx,
115115
p.remote.PlanResourceChange,
116116
translate.PlanResourceChangeRequest(req),
117117
translate.PlanResourceChangeResponse)
@@ -120,7 +120,7 @@ func (p provider) PlanResourceChange(
120120
func (p provider) ApplyResourceChange(
121121
ctx context.Context, req *tfprotov5.ApplyResourceChangeRequest,
122122
) (*tfprotov5.ApplyResourceChangeResponse, error) {
123-
return translateGRPC(ctx,
123+
return grpcutil.Translate(ctx,
124124
p.remote.ApplyResourceChange,
125125
translate.ApplyResourceChangeRequest(req),
126126
translate.ApplyResourceChangeResponse)
@@ -129,7 +129,7 @@ func (p provider) ApplyResourceChange(
129129
func (p provider) ImportResourceState(
130130
ctx context.Context, req *tfprotov5.ImportResourceStateRequest,
131131
) (*tfprotov5.ImportResourceStateResponse, error) {
132-
return translateGRPC(ctx,
132+
return grpcutil.Translate(ctx,
133133
p.remote.ImportResourceState,
134134
translate.ImportResourceStateRequest(req),
135135
translate.ImportResourceStateResponse)
@@ -138,7 +138,7 @@ func (p provider) ImportResourceState(
138138
func (p provider) MoveResourceState(
139139
ctx context.Context, req *tfprotov5.MoveResourceStateRequest,
140140
) (*tfprotov5.MoveResourceStateResponse, error) {
141-
return translateGRPC(ctx,
141+
return grpcutil.Translate(ctx,
142142
p.remote.MoveResourceState,
143143
translate.MoveResourceStateRequest(req),
144144
translate.MoveResourceStateResponse)
@@ -147,7 +147,7 @@ func (p provider) MoveResourceState(
147147
func (p provider) ValidateDataSourceConfig(
148148
ctx context.Context, req *tfprotov5.ValidateDataSourceConfigRequest,
149149
) (*tfprotov5.ValidateDataSourceConfigResponse, error) {
150-
return translateGRPC(ctx,
150+
return grpcutil.Translate(ctx,
151151
p.remote.ValidateDataSourceConfig,
152152
translate.ValidateDataSourceConfigRequest(req),
153153
translate.ValidateDataSourceConfigResponse)
@@ -156,7 +156,7 @@ func (p provider) ValidateDataSourceConfig(
156156
func (p provider) ReadDataSource(
157157
ctx context.Context, req *tfprotov5.ReadDataSourceRequest,
158158
) (*tfprotov5.ReadDataSourceResponse, error) {
159-
return translateGRPC(ctx,
159+
return grpcutil.Translate(ctx,
160160
p.remote.ReadDataSource,
161161
translate.ReadDataSourceRequest(req),
162162
translate.ReadDataSourceResponse)
@@ -165,7 +165,7 @@ func (p provider) ReadDataSource(
165165
func (p provider) CallFunction(
166166
ctx context.Context, req *tfprotov5.CallFunctionRequest,
167167
) (*tfprotov5.CallFunctionResponse, error) {
168-
return translateGRPC(ctx,
168+
return grpcutil.Translate(ctx,
169169
p.remote.CallFunction,
170170
translate.CallFunctionRequest(req),
171171
translate.CallFunctionResponse)
@@ -174,26 +174,8 @@ func (p provider) CallFunction(
174174
func (p provider) GetFunctions(
175175
ctx context.Context, req *tfprotov5.GetFunctionsRequest,
176176
) (*tfprotov5.GetFunctionsResponse, error) {
177-
return translateGRPC(ctx,
177+
return grpcutil.Translate(ctx,
178178
p.remote.GetFunctions,
179179
translate.GetFunctionsRequest(req),
180180
translate.GetFunctionsResponse)
181181
}
182-
183-
func translateGRPC[
184-
In, Out, Final any,
185-
Call func(context.Context, In, ...grpc.CallOption) (Out, error),
186-
MapResult func(Out) Final,
187-
](
188-
ctx context.Context,
189-
call Call,
190-
i In,
191-
m MapResult,
192-
) (Final, error) {
193-
v, err := call(ctx, i)
194-
if err != nil {
195-
var tmp Final
196-
return tmp, err
197-
}
198-
return m(v), nil
199-
}

0 commit comments

Comments
 (0)