Skip to content

Commit d10efd5

Browse files
edwardrfedw-defanglionello
authored
Remove grpc client and project from providers (#813)
* WIP: remove provider project name and grpc client * Remove grpc client and project from providers * Add delegateDomain to provider.Delete * Put projectName and delegate domain to requests * Fix domain delegation * Fix tests * Fix deploy and remove delegationSetId from aws byoc * Fix tail missing project name * Fix create upload URL needing setup cd and project name * Move project load out from commands to cli.Debug * Remove commented out code Co-authored-by: Lio李歐 <[email protected]> * Remove commented out code Co-authored-by: Lio李歐 <[email protected]> * Rename populate dubug request to query * Use b.getProjectDomain to set DOMAIN env var for CD * Use the correct domain * Fix missing delegation set ID from deploy to cd command * Remove cdImageTag state from byoc providers * create loader and provider only when needed. Prompt for provider when providerAuto is selected * Address PR comments * Fix typo Co-authored-by: Lio李歐 <[email protected]> * fix clent creation not writing to global client * Loader cache loaded project to prevent extra loading warning --------- Co-authored-by: Edward J <[email protected]> Co-authored-by: Lio李歐 <[email protected]>
1 parent f05dbb3 commit d10efd5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1487
-1244
lines changed

src/cmd/cli/command/commands.go

Lines changed: 149 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ func P(name string, value interface{}) cliClient.Property {
3939

4040
// GLOBALS
4141
var (
42-
client cliClient.FabricClient
43-
provider cliClient.Provider
42+
client cliClient.GrpcClient
4443
cluster string
4544
colorMode = ColorAuto
4645
doDebug = false
@@ -92,7 +91,11 @@ func Execute(ctx context.Context) error {
9291

9392
if strings.Contains(err.Error(), "maximum number of projects") {
9493
projectName := "<name>"
95-
if resp, err := provider.GetServices(ctx); err == nil {
94+
provider, err := getProvider(ctx)
95+
if err != nil {
96+
return err
97+
}
98+
if resp, err := provider.GetServices(ctx, &defangv1.GetServicesRequest{Project: projectName}); err == nil {
9699
projectName = resp.Project
97100
}
98101
printDefangHint("To deactivate a project, do:", "compose down --project-name "+projectName)
@@ -136,7 +139,7 @@ func Execute(ctx context.Context) error {
136139
return nil
137140
}
138141

139-
func SetupCommands(version string) {
142+
func SetupCommands(ctx context.Context, version string) {
140143
RootCmd.Version = version
141144
RootCmd.PersistentFlags().Var(&colorMode, "color", fmt.Sprintf(`colorize output; one of %v`, allColorModes))
142145
RootCmd.PersistentFlags().StringVarP(&cluster, "cluster", "s", cli.DefangFabric, "Defang cluster to connect to")
@@ -153,7 +156,7 @@ func SetupCommands(version string) {
153156
_ = RootCmd.MarkPersistentFlagFilename("file", "yml", "yaml")
154157

155158
// Setup tracking client
156-
track.Fabric = cli.Connect(cluster, nil)
159+
track.Fabric = cli.NewGrpcClient(ctx, cluster)
157160

158161
// CD command
159162
RootCmd.AddCommand(cdCmd)
@@ -299,42 +302,20 @@ var RootCmd = &cobra.Command{
299302
term.ForceColor(true)
300303
}
301304

302-
switch providerID {
303-
case cliClient.ProviderAuto:
304-
if awsInEnv() {
305-
term.Warn("Using Defang playground, but AWS environment variables were detected; did you forget --provider=aws or DEFANG_PROVIDER=aws?")
306-
}
307-
if doInEnv() {
308-
term.Warn("Using Defang playground, but DIGITALOCEAN_TOKEN environment variable was detected; did you forget --provider=digitalocean or DEFANG_PROVIDER=digitalocean?")
309-
}
310-
providerID = cliClient.ProviderDefang
311-
case cliClient.ProviderAWS:
312-
if !awsInEnv() {
313-
term.Warn("AWS provider was selected, but AWS environment variables are not set")
314-
}
315-
case cliClient.ProviderDO:
316-
if !doInEnv() {
317-
term.Warn("DigitalOcean provider was selected, but DIGITALOCEAN_TOKEN environment variable is not set")
318-
}
319-
case cliClient.ProviderDefang:
320-
// Ignore any env vars when explicitly using the Defang playground provider
321-
}
322-
323305
cwd, _ := cmd.Flags().GetString("cwd")
324306
if cwd != "" {
325307
// Change directory before running the command
326308
if err = os.Chdir(cwd); err != nil {
327309
return err
328310
}
329311
}
330-
loader := configureLoader(cmd)
331-
client, provider = cli.NewClient(cmd.Context(), cluster, providerID, loader)
312+
client = cli.NewGrpcClient(cmd.Context(), cluster)
332313

333314
if v, err := client.GetVersions(cmd.Context()); err == nil {
334315
version := cmd.Root().Version // HACK to avoid circular dependency with RootCmd
335316
term.Debug("Fabric:", v.Fabric, "CLI:", version, "CLI-Min:", v.CliMin)
336317
if hasTty && isNewer(version, v.CliMin) {
337-
term.Warn("Your CLI version is outdated. Please upgrade to the latest version by running:\n\ndefang upgrade")
318+
term.Warn("Your CLI version is outdated. Please upgrade to the latest version by running:\n\n defang upgrade\n")
338319
os.Setenv("DEFANG_HIDE_UPDATE", "1") // hide the upgrade hint at the end
339320
}
340321
}
@@ -358,9 +339,8 @@ var RootCmd = &cobra.Command{
358339
return err
359340
}
360341

361-
// FIXME: the new login might have changed the tenant, so we should reload the project
362-
client, provider = cli.NewClient(cmd.Context(), cluster, providerID, loader) // reconnect with the new token
363-
if err = client.CheckLoginAndToS(cmd.Context()); err == nil { // recheck (new token = new user)
342+
client = cli.NewGrpcClient(cmd.Context(), cluster) // reconnect with the new token
343+
if err = client.CheckLoginAndToS(cmd.Context()); err == nil { // recheck (new token = new user)
364344
return nil // success
365345
}
366346
}
@@ -405,6 +385,10 @@ var whoamiCmd = &cobra.Command{
405385
Args: cobra.NoArgs,
406386
Short: "Show the current user",
407387
RunE: func(cmd *cobra.Command, args []string) error {
388+
provider, err := getProvider(cmd.Context())
389+
if err != nil {
390+
return err
391+
}
408392
str, err := cli.Whoami(cmd.Context(), client, provider)
409393
if err != nil {
410394
return err
@@ -427,10 +411,15 @@ var certGenerateCmd = &cobra.Command{
427411
Args: cobra.NoArgs,
428412
Short: "Generate a TLS certificate",
429413
RunE: func(cmd *cobra.Command, args []string) error {
430-
err := cli.GenerateLetsEncryptCert(cmd.Context(), client, provider)
414+
loader := configureLoader(cmd)
415+
provider, err := getProvider(cmd.Context())
431416
if err != nil {
432417
return err
433418
}
419+
420+
if err := cli.GenerateLetsEncryptCert(cmd.Context(), loader, client, provider); err != nil {
421+
return err
422+
}
434423
return nil
435424
},
436425
}
@@ -670,11 +659,16 @@ var configSetCmd = &cobra.Command{
670659
fromEnv, _ := cmd.Flags().GetBool("env")
671660

672661
// Make sure we have a project to set config for before asking for a value
673-
_, err := provider.LoadProjectName(cmd.Context())
662+
loader := configureLoader(cmd)
663+
provider, err := getProvider(cmd.Context())
674664
if err != nil {
675665
return err
676666
}
677667

668+
if _, err := cli.LoadProjectName(cmd.Context(), loader, provider); err != nil {
669+
return err
670+
}
671+
678672
parts := strings.SplitN(args[0], "=", 2)
679673
name := parts[0]
680674

@@ -725,7 +719,7 @@ var configSetCmd = &cobra.Command{
725719
}
726720
}
727721

728-
if err := cli.ConfigSet(cmd.Context(), provider, name, value); err != nil {
722+
if err := cli.ConfigSet(cmd.Context(), loader, provider, name, value); err != nil {
729723
return err
730724
}
731725
term.Info("Updated value for", name)
@@ -742,7 +736,12 @@ var configDeleteCmd = &cobra.Command{
742736
Aliases: []string{"del", "delete", "remove"},
743737
Short: "Removes one or more config values",
744738
RunE: func(cmd *cobra.Command, names []string) error {
745-
if err := cli.ConfigDelete(cmd.Context(), provider, names...); err != nil {
739+
loader := configureLoader(cmd)
740+
provider, err := getProvider(cmd.Context())
741+
if err != nil {
742+
return err
743+
}
744+
if err := cli.ConfigDelete(cmd.Context(), loader, provider, names...); err != nil {
746745
// Show a warning (not an error) if the config was not found
747746
if connect.CodeOf(err) == connect.CodeNotFound {
748747
term.Warn(prettyError(err))
@@ -764,7 +763,12 @@ var configListCmd = &cobra.Command{
764763
Aliases: []string{"list"},
765764
Short: "List configs",
766765
RunE: func(cmd *cobra.Command, args []string) error {
767-
return cli.ConfigList(cmd.Context(), provider)
766+
loader := configureLoader(cmd)
767+
provider, err := getProvider(cmd.Context())
768+
if err != nil {
769+
return err
770+
}
771+
return cli.ConfigList(cmd.Context(), loader, provider)
768772
},
769773
}
770774

@@ -776,12 +780,12 @@ var debugCmd = &cobra.Command{
776780
RunE: func(cmd *cobra.Command, args []string) error {
777781
etag, _ := cmd.Flags().GetString("etag")
778782

779-
project, err := provider.LoadProject(cmd.Context())
783+
loader := configureLoader(cmd)
784+
provider, err := getProvider(cmd.Context())
780785
if err != nil {
781786
return err
782787
}
783-
784-
return cli.Debug(cmd.Context(), provider, etag, project, args)
788+
return cli.Debug(cmd.Context(), loader, client, provider, etag, nil, args)
785789
},
786790
}
787791

@@ -795,8 +799,13 @@ var deleteCmd = &cobra.Command{
795799
RunE: func(cmd *cobra.Command, names []string) error {
796800
var tail, _ = cmd.Flags().GetBool("tail")
797801

802+
loader := configureLoader(cmd)
803+
provider, err := getProvider(cmd.Context())
804+
if err != nil {
805+
return err
806+
}
798807
since := time.Now()
799-
etag, err := cli.Delete(cmd.Context(), provider, names...)
808+
etag, err := cli.Delete(cmd.Context(), loader, client, provider, names...)
800809
if err != nil {
801810
if connect.CodeOf(err) == connect.CodeNotFound {
802811
// Show a warning (not an error) if the service was not found
@@ -820,7 +829,7 @@ var deleteCmd = &cobra.Command{
820829
Raw: false,
821830
Verbose: verbose,
822831
}
823-
return cli.Tail(cmd.Context(), provider, tailParams)
832+
return cli.Tail(cmd.Context(), loader, provider, tailParams)
824833
},
825834
}
826835

@@ -892,7 +901,12 @@ var cdDestroyCmd = &cobra.Command{
892901
Args: cobra.NoArgs, // TODO: set MaximumNArgs(1),
893902
Short: "Destroy the service stack",
894903
RunE: func(cmd *cobra.Command, args []string) error {
895-
return cli.BootstrapCommand(cmd.Context(), provider, "destroy")
904+
loader := configureLoader(cmd)
905+
provider, err := getProvider(cmd.Context())
906+
if err != nil {
907+
return err
908+
}
909+
return cli.BootstrapCommand(cmd.Context(), loader, client, provider, "destroy")
896910
},
897911
}
898912

@@ -901,7 +915,12 @@ var cdDownCmd = &cobra.Command{
901915
Args: cobra.NoArgs, // TODO: set MaximumNArgs(1),
902916
Short: "Refresh and then destroy the service stack",
903917
RunE: func(cmd *cobra.Command, args []string) error {
904-
return cli.BootstrapCommand(cmd.Context(), provider, "down")
918+
loader := configureLoader(cmd)
919+
provider, err := getProvider(cmd.Context())
920+
if err != nil {
921+
return err
922+
}
923+
return cli.BootstrapCommand(cmd.Context(), loader, client, provider, "down")
905924
},
906925
}
907926

@@ -910,7 +929,12 @@ var cdRefreshCmd = &cobra.Command{
910929
Args: cobra.NoArgs, // TODO: set MaximumNArgs(1),
911930
Short: "Refresh the service stack",
912931
RunE: func(cmd *cobra.Command, args []string) error {
913-
return cli.BootstrapCommand(cmd.Context(), provider, "refresh")
932+
loader := configureLoader(cmd)
933+
provider, err := getProvider(cmd.Context())
934+
if err != nil {
935+
return err
936+
}
937+
return cli.BootstrapCommand(cmd.Context(), loader, client, provider, "refresh")
914938
},
915939
}
916940

@@ -919,7 +943,12 @@ var cdCancelCmd = &cobra.Command{
919943
Args: cobra.NoArgs, // TODO: set MaximumNArgs(1),
920944
Short: "Cancel the current CD operation",
921945
RunE: func(cmd *cobra.Command, args []string) error {
922-
return cli.BootstrapCommand(cmd.Context(), provider, "cancel")
946+
loader := configureLoader(cmd)
947+
provider, err := getProvider(cmd.Context())
948+
if err != nil {
949+
return err
950+
}
951+
return cli.BootstrapCommand(cmd.Context(), loader, client, provider, "cancel")
923952
},
924953
}
925954

@@ -930,6 +959,10 @@ var cdTearDownCmd = &cobra.Command{
930959
RunE: func(cmd *cobra.Command, args []string) error {
931960
force, _ := cmd.Flags().GetBool("force")
932961

962+
provider, err := getProvider(cmd.Context())
963+
if err != nil {
964+
return err
965+
}
933966
return cli.TearDown(cmd.Context(), provider, force)
934967
},
935968
}
@@ -942,8 +975,13 @@ var cdListCmd = &cobra.Command{
942975
RunE: func(cmd *cobra.Command, args []string) error {
943976
remote, _ := cmd.Flags().GetBool("remote")
944977

978+
loader := configureLoader(cmd)
979+
provider, err := getProvider(cmd.Context())
980+
if err != nil {
981+
return err
982+
}
945983
if remote {
946-
return cli.BootstrapCommand(cmd.Context(), provider, "list")
984+
return cli.BootstrapCommand(cmd.Context(), loader, client, provider, "list")
947985
}
948986
return cli.BootstrapLocalList(cmd.Context(), provider)
949987
},
@@ -955,11 +993,16 @@ var cdPreviewCmd = &cobra.Command{
955993
Annotations: authNeededAnnotation, // FIXME: because it still needs a delegated domain
956994
Short: "Preview the changes that will be made by the CD task",
957995
RunE: func(cmd *cobra.Command, args []string) error {
958-
resp, _, err := cli.ComposeUp(cmd.Context(), provider, compose.UploadModePreview, defangv1.DeploymentMode_UNSPECIFIED_MODE)
996+
loader := configureLoader(cmd)
997+
provider, err := getProvider(cmd.Context())
998+
if err != nil {
999+
return err
1000+
}
1001+
resp, _, err := cli.ComposeUp(cmd.Context(), loader, client, provider, compose.UploadModePreview, defangv1.DeploymentMode_UNSPECIFIED_MODE)
9591002
if err != nil {
9601003
return err
9611004
}
962-
return cli.Tail(cmd.Context(), provider, cli.TailOptions{
1005+
return cli.Tail(cmd.Context(), loader, provider, cli.TailOptions{
9631006
Etag: resp.Etag,
9641007
Verbose: verbose,
9651008
})
@@ -1002,7 +1045,7 @@ var upgradeCmd = &cobra.Command{
10021045
},
10031046
}
10041047

1005-
func configureLoader(cmd *cobra.Command) compose.Loader {
1048+
func configureLoader(cmd *cobra.Command) *compose.Loader {
10061049
configPaths, err := cmd.Flags().GetStringArray("file")
10071050
if err != nil {
10081051
panic(err)
@@ -1026,3 +1069,59 @@ func doInEnv() bool {
10261069
func IsCompletionCommand(cmd *cobra.Command) bool {
10271070
return cmd.Name() == cobra.ShellCompRequestCmd || (cmd.Parent() != nil && cmd.Parent().Name() == "completion")
10281071
}
1072+
1073+
var providerDescription = map[cliClient.ProviderID]string{
1074+
cliClient.ProviderDefang: "The Defang Playground is a free environment for testing only.",
1075+
cliClient.ProviderAWS: "Deploy to AWS using the AWS_* environment variables or the AWS CLI configuration.",
1076+
cliClient.ProviderDO: "Deploy to DigitalOcean using the DIGITALOCEAN_TOKEN, SPACES_ACCESS_KEY_ID, and SPACES_SECRET_ACCESS_KEY environment variables.",
1077+
}
1078+
1079+
func getProvider(ctx context.Context) (cliClient.Provider, error) {
1080+
switch providerID {
1081+
case cliClient.ProviderAuto:
1082+
if !nonInteractive {
1083+
// Prompt the user to choose a provider if in interactive mode
1084+
options := []string{}
1085+
for _, p := range cliClient.AllProviders() {
1086+
options = append(options, p.String())
1087+
}
1088+
var optionValue string
1089+
if err := survey.AskOne(&survey.Select{
1090+
Message: "Choose a cloud provider:",
1091+
Options: options,
1092+
Help: "The provider you choose will be used for deploying services.",
1093+
Description: func(value string, i int) string {
1094+
return providerDescription[cliClient.ProviderID(value)]
1095+
},
1096+
}, &optionValue); err != nil {
1097+
return nil, err
1098+
}
1099+
if err := providerID.Set(optionValue); err != nil {
1100+
panic(err)
1101+
}
1102+
term.Printf("To skip this prompt, set the DEFANG_PROVIDER=%s in your environment, or use:\n\n defang --provider=%s\n\n", optionValue, optionValue)
1103+
} else {
1104+
// Defaults to defang provider in non-interactive mode
1105+
if awsInEnv() {
1106+
term.Warn("Using Defang playground, but AWS environment variables were detected; did you forget --provider=aws or DEFANG_PROVIDER=aws?")
1107+
}
1108+
if doInEnv() {
1109+
term.Warn("Using Defang playground, but DIGITALOCEAN_TOKEN environment variable was detected; did you forget --provider=digitalocean or DEFANG_PROVIDER=digitalocean?")
1110+
}
1111+
providerID = cliClient.ProviderDefang
1112+
}
1113+
case cliClient.ProviderAWS:
1114+
if !awsInEnv() {
1115+
term.Warn("AWS provider was selected, but AWS environment variables are not set")
1116+
}
1117+
case cliClient.ProviderDO:
1118+
if !doInEnv() {
1119+
term.Warn("DigitalOcean provider was selected, but DIGITALOCEAN_TOKEN environment variable is not set")
1120+
}
1121+
case cliClient.ProviderDefang:
1122+
// Ignore any env vars when explicitly using the Defang playground provider
1123+
}
1124+
1125+
provider := cli.NewProvider(ctx, providerID, client)
1126+
return provider, nil
1127+
}

src/cmd/cli/command/commands_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ func TestVersion(t *testing.T) {
1717

1818
func testCommand(args []string) error {
1919
ctx := context.Background()
20-
SetupCommands("test")
20+
SetupCommands(ctx, "test")
2121
RootCmd.SetArgs(args)
2222
return RootCmd.ExecuteContext(ctx)
2323
}

0 commit comments

Comments
 (0)