Skip to content

Commit f95106d

Browse files
committed
Working prototype
1 parent e85fb74 commit f95106d

File tree

4 files changed

+19
-103
lines changed

4 files changed

+19
-103
lines changed

internal/command/stacks.go

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ func (c *StacksCommand) realRun(args []string, stdout, stderr io.Writer) int {
8888
1: {
8989
"stacks": &stacksplugin1.GRPCStacksPlugin{
9090
Metadata: c.pluginConfig.ToMetadata(),
91+
Services: c.Meta.Services,
9192
},
9293
},
9394
},

internal/stacksplugin/dynrpcserver/dependencies.go

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/stacksplugin/stacksplugin1/grpc_client.go

+10-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"log"
1111

1212
"github.com/hashicorp/go-plugin"
13+
"github.com/hashicorp/terraform-svchost/disco"
1314
"github.com/hashicorp/terraform/internal/stacksplugin"
1415
"github.com/hashicorp/terraform/internal/stacksplugin/dynrpcserver"
1516
"github.com/hashicorp/terraform/internal/stacksplugin/stacksproto1"
@@ -21,9 +22,10 @@ import (
2122

2223
// GRPCCloudClient is the client interface for interacting with terraform-cloudplugin
2324
type GRPCStacksClient struct {
24-
client stacksproto1.CommandServiceClient
25-
broker *plugin.GRPCBroker
26-
context context.Context
25+
client stacksproto1.CommandServiceClient
26+
broker *plugin.GRPCBroker
27+
services *disco.Disco
28+
context context.Context
2729
}
2830

2931
// Proof that GRPCStacksClient fulfills the go-plugin interface
@@ -32,6 +34,8 @@ var _ stacksplugin.Stacks1 = GRPCStacksClient{}
3234
// Execute sends the client Execute request and waits for the plugin to return
3335
// an exit code response before returning
3436
func (c GRPCStacksClient) Execute(args []string, stdout, stderr io.Writer) int {
37+
handles := newHandleTable()
38+
3539
dependenciesServer := dynrpcserver.NewDependenciesStub()
3640
packagesServer := dynrpcserver.NewPackagesStub()
3741
stacksServer := dynrpcserver.NewStacksStub()
@@ -40,6 +44,7 @@ func (c GRPCStacksClient) Execute(args []string, stdout, stderr io.Writer) int {
4044
dependenciesServerFunc := func(opts []grpc.ServerOption) *grpc.Server {
4145
s = grpc.NewServer(opts...)
4246
dep.RegisterDependenciesServer(s, dependenciesServer)
47+
dependenciesServer.ActivateRPCServer(newDependenciesServer(handles, c.services))
4348

4449
return s
4550
}
@@ -50,6 +55,7 @@ func (c GRPCStacksClient) Execute(args []string, stdout, stderr io.Writer) int {
5055
packagesServerFunc := func(opts []grpc.ServerOption) *grpc.Server {
5156
s = grpc.NewServer(opts...)
5257
pack.RegisterPackagesServer(s, packagesServer)
58+
packagesServer.ActivateRPCServer(newPackagesServer(c.services))
5359

5460
return s
5561
}
@@ -60,7 +66,7 @@ func (c GRPCStacksClient) Execute(args []string, stdout, stderr io.Writer) int {
6066
stacksServerFunc := func(opts []grpc.ServerOption) *grpc.Server {
6167
s = grpc.NewServer(opts...)
6268
stack.RegisterStacksServer(s, stacksServer)
63-
69+
stacksServer.ActivateRPCServer(newStacksServer(newStopper(), handles))
6470
return s
6571
}
6672

internal/stacksplugin/stacksplugin1/grpc_plugin.go

+7-98
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"net/rpc"
1010

1111
"github.com/hashicorp/go-plugin"
12+
"github.com/hashicorp/terraform-svchost/disco"
1213
"github.com/hashicorp/terraform/internal/stacksplugin"
1314
"github.com/hashicorp/terraform/internal/stacksplugin/stacksproto1"
1415
"google.golang.org/grpc"
@@ -21,6 +22,7 @@ type GRPCStacksPlugin struct {
2122
plugin.GRPCPlugin
2223
Metadata metadata.MD
2324
Impl stacksplugin.Stacks1
25+
Services *disco.Disco
2426
}
2527

2628
type GRPCStacksServer struct {
@@ -46,9 +48,10 @@ func (p *GRPCStacksPlugin) Client(*plugin.MuxBroker, *rpc.Client) (interface{},
4648
func (p *GRPCStacksPlugin) GRPCClient(ctx context.Context, broker *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) {
4749
ctx = metadata.NewOutgoingContext(ctx, p.Metadata)
4850
return &GRPCStacksClient{
49-
client: stacksproto1.NewCommandServiceClient(c),
50-
broker: broker,
51-
context: ctx,
51+
client: stacksproto1.NewCommandServiceClient(c),
52+
broker: broker,
53+
services: p.Services,
54+
context: ctx,
5255
}, nil
5356
}
5457

@@ -62,99 +65,5 @@ func (p *GRPCStacksPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server)
6265
})
6366
return nil
6467
*/
65-
return nil
66-
}
67-
68-
/**
69-
func registerGRPCServices(s *grpc.Server) {
70-
// We initially only register the setup server, because the registration
71-
// of other services can vary depending on the capabilities negotiated
72-
// during handshake.
73-
server := newSetupServer(serverHandshake(s))
74-
setup.RegisterSetupServer(s, server)
75-
}
76-
77-
func serverHandshake(s *grpc.Server) func(context.Context, *setup.Handshake_Request, *stopper) (*setup.ServerCapabilities, error) {
78-
dependenciesStub := dynrpcserver.NewDependenciesStub()
79-
dependencies.RegisterDependenciesServer(s, dependenciesStub)
80-
stacksStub := dynrpcserver.NewStacksStub()
81-
stacks.RegisterStacksServer(s, stacksStub)
82-
packagesStub := dynrpcserver.NewPackagesStub()
83-
packages.RegisterPackagesServer(s, packagesStub)
84-
85-
return func(ctx context.Context, request *setup.Handshake_Request, stopper *stopper) (*setup.ServerCapabilities, error) {
86-
// All of our servers will share a common handles table so that objects
87-
// can be passed from one service to another.
88-
handles := newHandleTable()
89-
90-
// NOTE: This is intentionally not the same disco that "package main"
91-
// instantiates for Terraform CLI, because the RPC API is
92-
// architecturally independent from CLI despite being launched through
93-
// it, and so it is not subject to any ambient CLI configuration files
94-
// that might be in scope. If we later discover requirements for
95-
// callers to customize the service discovery settings, consider
96-
// adding new fields to terraform1.ClientCapabilities (even though
97-
// this isn't strictly a "capability") so that the RPC caller has
98-
// full control without needing to also tinker with the current user's
99-
// CLI configuration.
100-
services, err := newServiceDisco(request.GetConfig())
101-
if err != nil {
102-
return &setup.ServerCapabilities{}, err
103-
}
104-
105-
// If handshaking is successful (which it currently always is, because
106-
// we don't have any special capabilities to negotiate yet) then we
107-
// will initialize all of the other services so the client can begin
108-
// doing real work. In future the details of what we register here
109-
// might vary based on the negotiated capabilities.
110-
dependenciesStub.ActivateRPCServer(newDependenciesServer(handles, services))
111-
stacksStub.ActivateRPCServer(newStacksServer(stopper, handles))
112-
packagesStub.ActivateRPCServer(newPackagesServer(services))
113-
114-
// If the client requested any extra capabililties that we're going
115-
// to honor then we should announce them in this result.
116-
return &setup.ServerCapabilities{}, nil
117-
}
118-
}
119-
120-
// serviceOpts are options that could potentially apply to all of our
121-
// individual RPC services.
122-
//
123-
// This could potentially be embedded inside a service-specific options
124-
// structure, if needed.
125-
type serviceOpts struct {
126-
experimentsAllowed bool
127-
}
128-
129-
func newServiceDisco(config *setup.Config) (*disco.Disco, error) {
130-
// First, we'll try and load any credentials that might have been available
131-
// to the UI. It's perfectly fine if there are none so any errors we find
132-
// are from malformed credentials rather than missing ones.
133-
134-
file, diags := cliconfig.LoadConfig()
135-
if diags.HasErrors() {
136-
return nil, fmt.Errorf("problem loading CLI configuration: %w", diags.ErrWithWarnings())
137-
}
138-
139-
helperPlugins := pluginDiscovery.FindPlugins("credentials", cliconfig.GlobalPluginDirs())
140-
src, err := file.CredentialsSource(helperPlugins)
141-
if err != nil {
142-
return nil, fmt.Errorf("problem creating credentials source: %w", err)
143-
}
144-
services := disco.NewWithCredentialsSource(src)
145-
146-
// Second, we'll side-load any credentials that might have been passed in.
147-
148-
credSrc := services.CredentialsSource()
149-
if config != nil {
150-
for host, cred := range config.GetCredentials() {
151-
if err := credSrc.StoreForHost(svchost.Hostname(host), auth.HostCredentialsToken(cred.Token)); err != nil {
152-
return nil, fmt.Errorf("problem storing credential for host %s with: %w", host, err)
153-
}
154-
}
155-
services.SetCredentialsSource(credSrc)
156-
}
157-
158-
return services, nil
68+
return errors.ErrUnsupported
15969
}
160-
**/

0 commit comments

Comments
 (0)