Skip to content

Commit 523bdd5

Browse files
committed
Merge branch 'main' into edw-remove-pg-byod-warning
2 parents 73262f4 + dc53ca5 commit 523bdd5

File tree

6 files changed

+154
-127
lines changed

6 files changed

+154
-127
lines changed

src/cmd/cli/command/track.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ func Track(name string, props ...P) {
2323
if disableAnalytics {
2424
return
2525
}
26+
var client cliClient.FabricClient = client
2627
if client == nil {
2728
client, _ = cli.Connect(cluster, nil)
2829
}
2930
trackWG.Add(1)
30-
go func(client cliClient.Client) {
31+
go func(client cliClient.FabricClient) {
3132
defer trackWG.Done()
3233
_ = client.Track(name, props...)
3334
}(client)

src/pkg/cli/client/client.go

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,37 +20,40 @@ type ProjectLoader interface {
2020
LoadWithProjectName(string) (*compose.Project, error)
2121
}
2222

23-
type Client interface {
24-
// Promote(google.protobuf.Empty) returns (google.protobuf.Empty);
25-
// Subscribe(context.Context, *v1.SubscribeRequest) (*v1.SubscribeResponse, error)
26-
// Update(context.Context, *v1.Service) (*v1.ServiceInfo, error)
23+
type FabricClient interface {
2724
AgreeToS(context.Context) error
25+
CheckLoginAndToS(context.Context) error
26+
DelegateSubdomainZone(context.Context, *defangv1.DelegateSubdomainZoneRequest) (*defangv1.DelegateSubdomainZoneResponse, error)
27+
DeleteSubdomainZone(context.Context) error
28+
GenerateFiles(context.Context, *defangv1.GenerateFilesRequest) (*defangv1.GenerateFilesResponse, error)
29+
GetDelegateSubdomainZone(context.Context) (*defangv1.DelegateSubdomainZoneResponse, error)
30+
GetVersions(context.Context) (*defangv1.Version, error)
31+
Publish(context.Context, *defangv1.PublishRequest) error
32+
RevokeToken(context.Context) error
33+
// Subscribe(context.Context, *v1.SubscribeRequest) (*v1.SubscribeResponse, error)
34+
Token(context.Context, *defangv1.TokenRequest) (*defangv1.TokenResponse, error)
35+
Track(string, ...Property) error
36+
}
37+
38+
type Client interface {
39+
FabricClient
40+
2841
BootstrapCommand(context.Context, string) (types.ETag, error)
2942
BootstrapList(context.Context) ([]string, error)
30-
CheckLoginAndToS(context.Context) error
3143
CreateUploadURL(context.Context, *defangv1.UploadURLRequest) (*defangv1.UploadURLResponse, error)
32-
DelegateSubdomainZone(context.Context, *defangv1.DelegateSubdomainZoneRequest) (*defangv1.DelegateSubdomainZoneResponse, error)
3344
// Deprecated: Use Deploy or Destroy instead.
3445
Delete(context.Context, *defangv1.DeleteRequest) (*defangv1.DeleteResponse, error)
3546
DeleteConfig(context.Context, *defangv1.Secrets) error
36-
DeleteSubdomainZone(context.Context) error
3747
Deploy(context.Context, *defangv1.DeployRequest) (*defangv1.DeployResponse, error)
3848
Destroy(context.Context) (types.ETag, error)
39-
GenerateFiles(context.Context, *defangv1.GenerateFilesRequest) (*defangv1.GenerateFilesResponse, error)
40-
GetDelegateSubdomainZone(context.Context) (*defangv1.DelegateSubdomainZoneResponse, error)
4149
GetService(context.Context, *defangv1.ServiceID) (*defangv1.ServiceInfo, error)
4250
GetServices(context.Context) (*defangv1.ListServicesResponse, error)
43-
GetVersions(context.Context) (*defangv1.Version, error)
4451
ListConfig(context.Context) (*defangv1.Secrets, error)
45-
Publish(context.Context, *defangv1.PublishRequest) error
4652
PutConfig(context.Context, *defangv1.SecretValue) error
4753
Restart(context.Context, ...string) (types.ETag, error)
48-
RevokeToken(context.Context) error
4954
ServiceDNS(name string) string
5055
Tail(context.Context, *defangv1.TailRequest) (ServerStream[defangv1.TailResponse], error)
5156
TearDown(context.Context) error
52-
Token(context.Context, *defangv1.TokenRequest) (*defangv1.TokenResponse, error)
53-
Track(string, ...Property) error
5457
WhoAmI(context.Context) (*defangv1.WhoAmIResponse, error)
5558

5659
LoadProject() (*compose.Project, error)

src/pkg/cli/client/grpc.go

Lines changed: 2 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package client
33
import (
44
"context"
55
"encoding/json"
6-
"errors"
76
"fmt"
87
"net/http"
98
"os"
@@ -17,7 +16,6 @@ import (
1716
defangv1 "github.com/DefangLabs/defang/src/protos/io/defang/v1"
1817
"github.com/DefangLabs/defang/src/protos/io/defang/v1/defangv1connect"
1918
"github.com/bufbuild/connect-go"
20-
compose "github.com/compose-spec/compose-go/v2/types"
2119
"github.com/google/uuid"
2220
"google.golang.org/protobuf/types/known/emptypb"
2321
)
@@ -30,6 +28,8 @@ type GrpcClient struct {
3028
Loader ProjectLoader
3129
}
3230

31+
var _ FabricClient = &GrpcClient{}
32+
3333
func NewGrpcClient(host, accessToken string, tenantID types.TenantID, loader ProjectLoader) *GrpcClient {
3434
baseUrl := "http://"
3535
if strings.HasSuffix(host, ":443") {
@@ -62,11 +62,6 @@ func getMsg[T any](resp *connect.Response[T], err error) (*T, error) {
6262
return resp.Msg, nil
6363
}
6464

65-
func (g GrpcClient) LoadProject() (*compose.Project, error) {
66-
projectName, _ := g.LoadProjectName()
67-
return g.Loader.LoadWithDefaultProjectName(projectName)
68-
}
69-
7065
func (g GrpcClient) GetVersions(ctx context.Context) (*defangv1.Version, error) {
7166
return getMsg(g.client.GetVersion(ctx, &connect.Request[emptypb.Empty]{}))
7267
}
@@ -81,53 +76,15 @@ func (g GrpcClient) RevokeToken(ctx context.Context) error {
8176
return err
8277
}
8378

84-
func (g GrpcClient) Update(ctx context.Context, req *defangv1.Service) (*defangv1.ServiceInfo, error) {
85-
return getMsg(g.client.Update(ctx, connect.NewRequest(req)))
86-
}
87-
88-
func (g GrpcClient) Deploy(ctx context.Context, req *defangv1.DeployRequest) (*defangv1.DeployResponse, error) {
89-
return getMsg(g.client.Deploy(ctx, connect.NewRequest(req)))
90-
}
91-
92-
func (g GrpcClient) GetService(ctx context.Context, req *defangv1.ServiceID) (*defangv1.ServiceInfo, error) {
93-
return getMsg(g.client.Get(ctx, connect.NewRequest(req)))
94-
}
95-
96-
func (g GrpcClient) Delete(ctx context.Context, req *defangv1.DeleteRequest) (*defangv1.DeleteResponse, error) {
97-
return getMsg(g.client.Delete(ctx, connect.NewRequest(req)))
98-
}
99-
10079
func (g GrpcClient) Publish(ctx context.Context, req *defangv1.PublishRequest) error {
10180
_, err := g.client.Publish(ctx, connect.NewRequest(req))
10281
return err
10382
}
10483

105-
func (g GrpcClient) GetServices(ctx context.Context) (*defangv1.ListServicesResponse, error) {
106-
return getMsg(g.client.GetServices(ctx, &connect.Request[emptypb.Empty]{}))
107-
}
108-
10984
func (g GrpcClient) GenerateFiles(ctx context.Context, req *defangv1.GenerateFilesRequest) (*defangv1.GenerateFilesResponse, error) {
11085
return getMsg(g.client.GenerateFiles(ctx, connect.NewRequest(req)))
11186
}
11287

113-
func (g GrpcClient) PutConfig(ctx context.Context, req *defangv1.SecretValue) error {
114-
_, err := g.client.PutSecret(ctx, connect.NewRequest(req))
115-
return err
116-
}
117-
118-
func (g GrpcClient) DeleteConfig(ctx context.Context, req *defangv1.Secrets) error {
119-
_, err := g.client.DeleteSecrets(ctx, connect.NewRequest(&defangv1.Secrets{Names: req.Names}))
120-
return err
121-
}
122-
123-
func (g GrpcClient) ListConfig(ctx context.Context) (*defangv1.Secrets, error) {
124-
return getMsg(g.client.ListSecrets(ctx, &connect.Request[emptypb.Empty]{}))
125-
}
126-
127-
func (g GrpcClient) CreateUploadURL(ctx context.Context, req *defangv1.UploadURLRequest) (*defangv1.UploadURLResponse, error) {
128-
return getMsg(g.client.CreateUploadURL(ctx, connect.NewRequest(req)))
129-
}
130-
13188
func (g GrpcClient) WhoAmI(ctx context.Context) (*defangv1.WhoAmIResponse, error) {
13289
return getMsg(g.client.WhoAmI(ctx, &connect.Request[emptypb.Empty]{}))
13390
}
@@ -145,14 +102,6 @@ func (g GrpcClient) GetDelegateSubdomainZone(ctx context.Context) (*defangv1.Del
145102
return getMsg(g.client.GetDelegateSubdomainZone(ctx, &connect.Request[emptypb.Empty]{}))
146103
}
147104

148-
func (g *GrpcClient) Tail(ctx context.Context, req *defangv1.TailRequest) (ServerStream[defangv1.TailResponse], error) {
149-
return g.client.Tail(ctx, connect.NewRequest(req))
150-
}
151-
152-
func (g *GrpcClient) BootstrapCommand(ctx context.Context, command string) (types.ETag, error) {
153-
return "", errors.New("the bootstrap command is not valid for the Defang provider")
154-
}
155-
156105
func (g *GrpcClient) AgreeToS(ctx context.Context) error {
157106
_, err := g.client.SignEULA(ctx, &connect.Request[emptypb.Empty]{})
158107
return err
@@ -183,58 +132,3 @@ func (g *GrpcClient) CheckLoginAndToS(ctx context.Context) error {
183132
_, err := g.client.CheckToS(ctx, &connect.Request[emptypb.Empty]{})
184133
return err
185134
}
186-
187-
func (g *GrpcClient) Destroy(ctx context.Context) (types.ETag, error) {
188-
// Get all the services in the project and delete them all at once
189-
project, err := g.GetServices(ctx)
190-
if err != nil {
191-
return "", err
192-
}
193-
if len(project.Services) == 0 {
194-
return "", errors.New("no services found")
195-
}
196-
var names []string
197-
for _, service := range project.Services {
198-
names = append(names, service.Service.Name)
199-
}
200-
resp, err := g.Delete(ctx, &defangv1.DeleteRequest{Names: names})
201-
if err != nil {
202-
return "", err
203-
}
204-
return resp.Etag, nil
205-
}
206-
207-
func (g *GrpcClient) TearDown(ctx context.Context) error {
208-
return errors.New("the teardown command is not valid for the Defang provider")
209-
}
210-
211-
func (g *GrpcClient) BootstrapList(context.Context) ([]string, error) {
212-
return nil, errors.New("this command is not valid for the Defang provider")
213-
}
214-
215-
func (g *GrpcClient) Restart(ctx context.Context, names ...string) (types.ETag, error) {
216-
// For now, we'll just get the service info and pass it back to Deploy as-is.
217-
services := make([]*defangv1.Service, 0, len(names))
218-
for _, name := range names {
219-
serviceInfo, err := g.GetService(ctx, &defangv1.ServiceID{Name: name})
220-
if err != nil {
221-
return "", err
222-
}
223-
services = append(services, serviceInfo.Service)
224-
}
225-
226-
dr, err := g.Deploy(ctx, &defangv1.DeployRequest{Services: services})
227-
if err != nil {
228-
return "", err
229-
}
230-
return dr.Etag, nil
231-
}
232-
233-
func (g GrpcClient) ServiceDNS(name string) string {
234-
whoami, _ := g.WhoAmI(context.TODO())
235-
return whoami.Tenant + "-" + name
236-
}
237-
238-
func (g GrpcClient) LoadProjectName() (string, error) {
239-
return string(g.tenantID), nil
240-
}

src/pkg/cli/client/playground.go

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package client
2+
3+
import (
4+
"context"
5+
"errors"
6+
7+
"github.com/DefangLabs/defang/src/pkg/term"
8+
"github.com/DefangLabs/defang/src/pkg/types"
9+
defangv1 "github.com/DefangLabs/defang/src/protos/io/defang/v1"
10+
"github.com/bufbuild/connect-go"
11+
compose "github.com/compose-spec/compose-go/v2/types"
12+
"google.golang.org/protobuf/types/known/emptypb"
13+
)
14+
15+
type PlaygroundClient struct {
16+
GrpcClient
17+
}
18+
19+
func (g PlaygroundClient) LoadProject() (*compose.Project, error) {
20+
projectName, _ := g.LoadProjectName()
21+
return g.Loader.LoadWithDefaultProjectName(projectName)
22+
}
23+
24+
func (g PlaygroundClient) Update(ctx context.Context, req *defangv1.Service) (*defangv1.ServiceInfo, error) {
25+
return getMsg(g.client.Update(ctx, connect.NewRequest(req)))
26+
}
27+
28+
func (g PlaygroundClient) Deploy(ctx context.Context, req *defangv1.DeployRequest) (*defangv1.DeployResponse, error) {
29+
// TODO: remove this when playground supports BYOD
30+
for _, service := range req.Services {
31+
if service.Domainname != "" {
32+
term.Warnf("Defang provider does not support the domainname field for now, service: %v, domain: %v", service.Name, service.Domainname)
33+
}
34+
}
35+
return getMsg(g.client.Deploy(ctx, connect.NewRequest(req)))
36+
}
37+
38+
func (g PlaygroundClient) GetService(ctx context.Context, req *defangv1.ServiceID) (*defangv1.ServiceInfo, error) {
39+
return getMsg(g.client.Get(ctx, connect.NewRequest(req)))
40+
}
41+
42+
func (g PlaygroundClient) Delete(ctx context.Context, req *defangv1.DeleteRequest) (*defangv1.DeleteResponse, error) {
43+
return getMsg(g.client.Delete(ctx, connect.NewRequest(req)))
44+
}
45+
46+
func (g PlaygroundClient) GetServices(ctx context.Context) (*defangv1.ListServicesResponse, error) {
47+
return getMsg(g.client.GetServices(ctx, &connect.Request[emptypb.Empty]{}))
48+
}
49+
50+
func (g PlaygroundClient) PutConfig(ctx context.Context, req *defangv1.SecretValue) error {
51+
_, err := g.client.PutSecret(ctx, connect.NewRequest(req))
52+
return err
53+
}
54+
55+
func (g PlaygroundClient) DeleteConfig(ctx context.Context, req *defangv1.Secrets) error {
56+
_, err := g.client.DeleteSecrets(ctx, connect.NewRequest(&defangv1.Secrets{Names: req.Names}))
57+
return err
58+
}
59+
60+
func (g PlaygroundClient) ListConfig(ctx context.Context) (*defangv1.Secrets, error) {
61+
return getMsg(g.client.ListSecrets(ctx, &connect.Request[emptypb.Empty]{}))
62+
}
63+
64+
func (g PlaygroundClient) CreateUploadURL(ctx context.Context, req *defangv1.UploadURLRequest) (*defangv1.UploadURLResponse, error) {
65+
return getMsg(g.client.CreateUploadURL(ctx, connect.NewRequest(req)))
66+
}
67+
68+
func (g *PlaygroundClient) Tail(ctx context.Context, req *defangv1.TailRequest) (ServerStream[defangv1.TailResponse], error) {
69+
return g.client.Tail(ctx, connect.NewRequest(req))
70+
}
71+
72+
func (g *PlaygroundClient) BootstrapCommand(ctx context.Context, command string) (types.ETag, error) {
73+
return "", errors.New("the bootstrap command is not valid for the Defang provider")
74+
}
75+
func (g *PlaygroundClient) Destroy(ctx context.Context) (types.ETag, error) {
76+
// Get all the services in the project and delete them all at once
77+
project, err := g.GetServices(ctx)
78+
if err != nil {
79+
return "", err
80+
}
81+
if len(project.Services) == 0 {
82+
return "", errors.New("no services found")
83+
}
84+
var names []string
85+
for _, service := range project.Services {
86+
names = append(names, service.Service.Name)
87+
}
88+
resp, err := g.Delete(ctx, &defangv1.DeleteRequest{Names: names})
89+
if err != nil {
90+
return "", err
91+
}
92+
return resp.Etag, nil
93+
}
94+
95+
func (g *PlaygroundClient) TearDown(ctx context.Context) error {
96+
return errors.New("the teardown command is not valid for the Defang provider")
97+
}
98+
99+
func (g *PlaygroundClient) BootstrapList(context.Context) ([]string, error) {
100+
return nil, errors.New("this command is not valid for the Defang provider")
101+
}
102+
103+
func (g *PlaygroundClient) Restart(ctx context.Context, names ...string) (types.ETag, error) {
104+
// For now, we'll just get the service info and pass it back to Deploy as-is.
105+
services := make([]*defangv1.Service, 0, len(names))
106+
for _, name := range names {
107+
serviceInfo, err := g.GetService(ctx, &defangv1.ServiceID{Name: name})
108+
if err != nil {
109+
return "", err
110+
}
111+
services = append(services, serviceInfo.Service)
112+
}
113+
114+
dr, err := g.Deploy(ctx, &defangv1.DeployRequest{Services: services})
115+
if err != nil {
116+
return "", err
117+
}
118+
return dr.Etag, nil
119+
}
120+
121+
func (g PlaygroundClient) ServiceDNS(name string) string {
122+
whoami, _ := g.WhoAmI(context.TODO())
123+
return whoami.Tenant + "-" + name
124+
}
125+
126+
func (g PlaygroundClient) LoadProjectName() (string, error) {
127+
return string(g.tenantID), nil
128+
}

src/pkg/cli/connect.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,14 @@ func Connect(cluster string, loader client.ProjectLoader) (*client.GrpcClient, t
7676
func NewClient(cluster string, provider client.Provider, loader client.ProjectLoader) client.Client {
7777
defangClient, tenantId := Connect(cluster, loader)
7878

79-
if provider == client.ProviderAWS {
79+
switch provider {
80+
case client.ProviderAWS:
8081
term.Info(" # Using AWS provider") // HACK: # prevents errors when evaluating the shell completion script
8182
byocClient := aws.NewByoc(tenantId, defangClient)
8283
return byocClient
84+
default:
85+
return &client.PlaygroundClient{*defangClient}
8386
}
84-
85-
return defangClient
8687
}
8788

8889
// Deprecated: don't rely on info in token

src/pkg/cli/login.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func NonInteractiveLogin(ctx context.Context, client client.Client, fabric strin
8282
term.Debug(" - Got GitHub Actions id-token")
8383
resp, err := client.Token(ctx, &defangv1.TokenRequest{
8484
Assertion: idToken,
85-
Scope: []string{"admin", "read"},
85+
Scope: []string{"admin", "read"}, // no "tail" scope
8686
})
8787
if err != nil {
8888
return err

0 commit comments

Comments
 (0)