Skip to content

Commit 22ba464

Browse files
committed
Add feature for cleaning old deployments
Signed-off-by: Spencer Judge <[email protected]>
1 parent 1b0555c commit 22ba464

File tree

7 files changed

+181
-85
lines changed

7 files changed

+181
-85
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
This isn't a real feature, rather it exists to clean up any old deployments in the cloud namespace
2+
that features might run against.
3+
4+
It starts with the `aa` prefix so that it'll run before other deployment related features. Very
5+
sophisticated, I know.
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package routing_with_ramp
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
"github.com/temporalio/features/harness/go/harness"
9+
"go.temporal.io/api/workflowservice/v1"
10+
"go.temporal.io/sdk/activity"
11+
"go.temporal.io/sdk/client"
12+
"go.temporal.io/sdk/workflow"
13+
)
14+
15+
var Feature = harness.Feature{
16+
Workflows: CleanOldDeployments,
17+
Activities: []any{ListOldDeployments, DeleteDeployment},
18+
Execute: func(ctx context.Context, runner *harness.Runner) (client.WorkflowRun, error) {
19+
run, err := runner.ExecuteDefault(ctx)
20+
if err != nil {
21+
return nil, err
22+
}
23+
return run, nil
24+
},
25+
}
26+
27+
func CleanOldDeployments(ctx workflow.Context) (string, error) {
28+
var deploymentsToClean []string
29+
ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
30+
StartToCloseTimeout: 1 * time.Minute,
31+
})
32+
err := workflow.ExecuteActivity(ctx, ListOldDeployments).Get(ctx, &deploymentsToClean)
33+
if err != nil {
34+
return "", err
35+
}
36+
37+
for _, deployment := range deploymentsToClean {
38+
err := workflow.ExecuteActivity(ctx, DeleteDeployment, deployment).Get(ctx, nil)
39+
if err != nil {
40+
return "", err
41+
}
42+
}
43+
return fmt.Sprintf("Cleaned %d deployments", len(deploymentsToClean)), nil
44+
}
45+
46+
func ListOldDeployments(ctx context.Context) ([]string, error) {
47+
tClient := activity.GetClient(ctx)
48+
49+
allDeployments := make([]string, 0)
50+
iterator, err := tClient.WorkerDeploymentClient().List(ctx, client.WorkerDeploymentListOptions{})
51+
if err != nil {
52+
return nil, err
53+
}
54+
for iterator.HasNext() {
55+
deployment, err := iterator.Next()
56+
if err != nil {
57+
return nil, err
58+
}
59+
if deployment.CreateTime.Before(time.Now().Add(-time.Hour * 24)) {
60+
allDeployments = append(allDeployments, deployment.Name)
61+
}
62+
}
63+
64+
if err != nil {
65+
return nil, err
66+
}
67+
return allDeployments, nil
68+
}
69+
70+
func DeleteDeployment(ctx context.Context, deploymentName string) error {
71+
client := activity.GetClient(ctx)
72+
ns := activity.GetInfo(ctx).WorkflowNamespace
73+
74+
deploymentInfo, err := client.WorkflowService().DescribeWorkerDeployment(
75+
ctx,
76+
&workflowservice.DescribeWorkerDeploymentRequest{
77+
Namespace: ns,
78+
DeploymentName: deploymentName,
79+
},
80+
)
81+
if err != nil {
82+
return fmt.Errorf("failed to describe worker deployment %s: %w", deploymentName, err)
83+
}
84+
// Unset current/ramping versions so things can be deleted
85+
_, err = client.WorkflowService().SetWorkerDeploymentCurrentVersion(ctx, &workflowservice.SetWorkerDeploymentCurrentVersionRequest{
86+
Namespace: ns,
87+
DeploymentName: deploymentName,
88+
Identity: "feature-deployment-deleter",
89+
IgnoreMissingTaskQueues: true,
90+
AllowNoPollers: true,
91+
})
92+
if err != nil {
93+
// Try using unversioned string (needed if deployment was very old)
94+
_, err = client.WorkflowService().SetWorkerDeploymentCurrentVersion(ctx, &workflowservice.SetWorkerDeploymentCurrentVersionRequest{
95+
Namespace: ns,
96+
DeploymentName: deploymentName,
97+
BuildId: "__unversioned__",
98+
Identity: "feature-deployment-deleter",
99+
IgnoreMissingTaskQueues: true,
100+
AllowNoPollers: true,
101+
})
102+
if err != nil {
103+
return fmt.Errorf("failed to unset current version for deployment %s: %w", deploymentName, err)
104+
}
105+
}
106+
_, err = client.WorkflowService().SetWorkerDeploymentRampingVersion(ctx, &workflowservice.SetWorkerDeploymentRampingVersionRequest{
107+
Namespace: ns,
108+
DeploymentName: deploymentName,
109+
Identity: "feature-deployment-deleter",
110+
IgnoreMissingTaskQueues: true,
111+
AllowNoPollers: true,
112+
})
113+
if err != nil {
114+
// Try using unversioned string (needed if deployment was very old)
115+
_, err = client.WorkflowService().SetWorkerDeploymentRampingVersion(ctx, &workflowservice.SetWorkerDeploymentRampingVersionRequest{
116+
Namespace: ns,
117+
DeploymentName: deploymentName,
118+
BuildId: "__unversioned__",
119+
Identity: "feature-deployment-deleter",
120+
IgnoreMissingTaskQueues: true,
121+
AllowNoPollers: true,
122+
})
123+
if err != nil {
124+
return fmt.Errorf("failed to unset ramping version for deployment %s: %w", deploymentName, err)
125+
}
126+
return fmt.Errorf("failed to unset ramping version for deployment %s: %w", deploymentName, err)
127+
}
128+
129+
for _, version := range deploymentInfo.WorkerDeploymentInfo.VersionSummaries {
130+
_, err = client.WorkflowService().DeleteWorkerDeploymentVersion(ctx,
131+
&workflowservice.DeleteWorkerDeploymentVersionRequest{
132+
Namespace: ns,
133+
DeploymentVersion: version.DeploymentVersion,
134+
SkipDrainage: true,
135+
Identity: "feature-deployment-deleter",
136+
},
137+
)
138+
if err != nil {
139+
return fmt.Errorf("failed to delete deployment version %s for deployment %s: %w",
140+
version.DeploymentVersion, deploymentName, err)
141+
}
142+
}
143+
144+
client.WorkflowService().DeleteWorkerDeployment(ctx,
145+
&workflowservice.DeleteWorkerDeploymentRequest{
146+
Namespace: ns,
147+
DeploymentName: deploymentName,
148+
Identity: "features-deployment-deleter",
149+
},
150+
)
151+
return nil
152+
}

features/features.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
data_converter_failure "github.com/temporalio/features/features/data_converter/failure"
2626
data_converter_json "github.com/temporalio/features/features/data_converter/json"
2727
data_converter_json_protobuf "github.com/temporalio/features/features/data_converter/json_protobuf"
28+
deployment_versioning_aa_clean_old_deployments "github.com/temporalio/features/features/deployment_versioning/aa_clean_old_deployments"
2829
deployment_versioning_routing_auto_upgrade "github.com/temporalio/features/features/deployment_versioning/routing_auto_upgrade"
2930
deployment_versioning_routing_pinned "github.com/temporalio/features/features/deployment_versioning/routing_pinned"
3031
deployment_versioning_routing_with_override "github.com/temporalio/features/features/deployment_versioning/routing_with_override"
@@ -84,6 +85,7 @@ func init() {
8485
data_converter_failure.Feature,
8586
data_converter_json_protobuf.Feature,
8687
data_converter_json.Feature,
88+
deployment_versioning_aa_clean_old_deployments.Feature,
8789
deployment_versioning_routing_auto_upgrade.Feature,
8890
deployment_versioning_routing_pinned.Feature,
8991
deployment_versioning_routing_with_override.Feature,

features/go.sum

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
6868
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
6969
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
7070
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
71-
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
7271
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
7372
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
7473
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -87,8 +86,8 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
8786
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
8887
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
8988
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
90-
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
91-
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
89+
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 h1:sGm2vDRFUrQJO/Veii4h4zG2vvqG6uWNkBHSTqXOZk0=
90+
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2/go.mod h1:wd1YpapPLivG6nQgbf7ZkG1hhSOXDhhn4MLTknx2aAc=
9291
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
9392
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys=
9493
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
@@ -183,26 +182,24 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
183182
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
184183
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
185184
go.temporal.io/api v1.5.0/go.mod h1:BqKxEJJYdxb5dqf0ODfzfMxh8UEQ5L3zKS51FiIYYkA=
186-
go.temporal.io/api v1.50.0 h1:7s8Cn+fKfNx9G0v2Ge9We6X2WiCA3JvJ9JryeNbx1Bc=
187-
go.temporal.io/api v1.50.0/go.mod h1:iaxoP/9OXMJcQkETTECfwYq4cw/bj4nwov8b3ZLVnXM=
185+
go.temporal.io/api v1.53.0 h1:6vAFpXaC584AIELa6pONV56MTpkm4Ha7gPWL2acNAjo=
186+
go.temporal.io/api v1.53.0/go.mod h1:iaxoP/9OXMJcQkETTECfwYq4cw/bj4nwov8b3ZLVnXM=
188187
go.temporal.io/sdk v1.12.0/go.mod h1:lSp3lH1lI0TyOsus0arnO3FYvjVXBZGi/G7DjnAnm6o=
189-
go.temporal.io/sdk v1.35.0 h1:lRNAQ5As9rLgYa7HBvnmKyzxLcdElTuoFJ0FXM/AsLQ=
190-
go.temporal.io/sdk v1.35.0/go.mod h1:1q5MuLc2MEJ4lneZTHJzpVebW2oZnyxoIOWX3oFVebw=
188+
go.temporal.io/sdk v1.37.0 h1:RbwCkUQuqY4rfCzdrDZF9lgT7QWG/pHlxfZFq0NPpDQ=
189+
go.temporal.io/sdk v1.37.0/go.mod h1:tOy6vGonfAjrpCl6Bbw/8slTgQMiqvoyegRv2ZHPm5M=
191190
go.temporal.io/sdk/contrib/tally v0.2.0 h1:XnTJIQcjOv+WuCJ1u8Ve2nq+s2H4i/fys34MnWDRrOo=
192191
go.temporal.io/sdk/contrib/tally v0.2.0/go.mod h1:1kpSuCms/tHeJQDPuuKkaBsMqfHnIIRnCtUYlPNXxuE=
193192
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
194193
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
195194
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
196195
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
197-
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
198196
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4=
199197
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
200198
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
201199
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
202200
go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec=
203201
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
204202
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
205-
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
206203
go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI=
207204
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
208205
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -270,7 +267,6 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
270267
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
271268
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
272269
golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
273-
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
274270
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
275271
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
276272
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -290,7 +286,6 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
290286
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
291287
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
292288
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
293-
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
294289
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
295290
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
296291
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -323,8 +318,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
323318
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
324319
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
325320
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
326-
google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
327-
google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
321+
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
322+
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
328323
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
329324
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
330325
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -337,8 +332,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
337332
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
338333
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
339334
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
340-
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
341-
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
335+
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
336+
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
342337
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
343338
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
344339
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

harness/go/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ require (
2121
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect
2222
github.com/gogo/protobuf v1.3.2 // indirect
2323
github.com/golang/mock v1.6.0 // indirect
24-
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
24+
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // indirect
2525
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
2626
github.com/nexus-rpc/sdk-go v0.3.0 // indirect
2727
github.com/pmezard/go-difflib v1.0.0 // indirect

0 commit comments

Comments
 (0)