Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/cmd/cli/command/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,8 @@ func SetupCommands(version string) {
// TODO: Add list, renew etc.
certCmd.AddCommand(certGenerateCmd)
RootCmd.AddCommand(certCmd)
recipeCmd := makeRecipeCmd()
RootCmd.AddCommand(recipeCmd)

stackCmd := makeStackCmd()
RootCmd.AddCommand(stackCmd)
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/cli/command/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ func makeComposeConfigCmd() *cobra.Command {
_, _, err = cli.ComposeUp(ctx, global.Client, sessionx.Provider, sessionx.Stack, cli.ComposeUpParams{
Project: project,
UploadMode: compose.UploadModeIgnore,
Mode: modes.ModeUnspecified,
Mode: modes.RecipeUnspecified,
})
if !errors.Is(err, dryrun.ErrDryRun) {
return err
Expand Down
7 changes: 5 additions & 2 deletions src/cmd/cli/command/estimate.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ func makeEstimateCmd() *cobra.Command {
var previewProvider client.Provider = &client.PlaygroundProvider{FabricClient: global.Client}

// default to development mode if not specified; TODO: when mode is not specified, show an interactive prompt
if global.Stack.Mode == modes.ModeUnspecified {
global.Stack.Mode = modes.ModeAffordable
if global.Stack.Mode == modes.RecipeUnspecified {
global.Stack.Mode = modes.RecipeAffordable
}
if region == "" {
region = client.GetRegion(global.Stack.Provider) // This sets the default region based on the provider
Expand All @@ -69,6 +69,7 @@ func makeEstimateCmd() *cobra.Command {

var providerDescription = map[client.ProviderID]string{
client.ProviderDefang: "The Defang Playground is a free platform intended for testing purposes only.",
client.ProviderAzure: "Deploy to Azure using the AZURE_CLIENT_ID, AZURE_TENANT_ID, and AZURE_CLIENT_SECRET environment variables or the Azure CLI configuration.",
client.ProviderAWS: "Deploy to AWS using the AWS_* environment variables or the AWS CLI configuration.",
client.ProviderDO: "Deploy to DigitalOcean using the DIGITALOCEAN_TOKEN, SPACES_ACCESS_KEY_ID, and SPACES_SECRET_ACCESS_KEY environment variables.",
client.ProviderGCP: "Deploy to Google Cloud Platform using gcloud Application Default Credentials.",
Expand All @@ -94,6 +95,8 @@ func interactiveSelectProvider(providers []client.ProviderID) (client.ProviderID
defaultOption = client.ProviderDO.String()
case pkg.GcpInEnv() != "":
defaultOption = client.ProviderGCP.String()
case pkg.AzureInEnv() != "":
defaultOption = client.ProviderAzure.String()
}

var optionValue string
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/cli/command/estimate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func TestPrintEstimate(t *testing.T) {
}

stdout, _ := term.SetupTestTerm(t)
cli.PrintEstimate(modes.ModeAffordable, estimate, term.DefaultTerm)
cli.PrintEstimate(modes.RecipeAffordable, estimate, term.DefaultTerm)

expectedOutput := `
Estimate for Deployment Mode: AFFORDABLE
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/cli/command/globals.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func NewGlobalConfig() *GlobalConfig {
}
}

mode := modes.ModeUnspecified
mode := modes.RecipeUnspecified
if fromEnv, ok := os.LookupEnv("DEFANG_MODE"); ok {
err := mode.Set(fromEnv)
if err != nil {
Expand Down Expand Up @@ -158,7 +158,7 @@ func (global *GlobalConfig) ToMap() map[string]string {
if regionVarName != "" && global.Stack.Region != "" {
m[regionVarName] = global.Stack.Region
}
if global.Stack.Mode != modes.ModeUnspecified {
if global.Stack.Mode != modes.RecipeUnspecified {
m["DEFANG_MODE"] = global.Stack.Mode.String()
}
m["DEFANG_VERBOSE"] = strconv.FormatBool(global.Verbose)
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/cli/command/globals_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func Test_configurationPrecedence(t *testing.T) {
HideUpdate: false,
NonInteractive: false, // set to false just for test instead of !term.IsTerminal() for consistency
Verbose: false,
Stack: stacks.Parameters{Provider: client.ProviderAuto, Mode: modes.ModeUnspecified},
Stack: stacks.Parameters{Provider: client.ProviderAuto, Mode: modes.RecipeUnspecified},
FabricAddr: "",
Tenant: "",
}
Expand Down
93 changes: 93 additions & 0 deletions src/cmd/cli/command/recipe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package command

import (
"errors"

"github.com/DefangLabs/defang/src/pkg/cli"
"github.com/spf13/cobra"
)

func makeRecipeCmd() *cobra.Command {
var recipeCmd = &cobra.Command{
Use: "recipe",
Aliases: []string{"recipes", "modes", "mode"},
Short: "Manage workspace recipes (deployment modes)",
}
recipeListCmd := makeRecipeListCmd()
recipeCmd.AddCommand(recipeListCmd)
recipeShowCmd := makeRecipeShowCmd()
recipeCmd.AddCommand(recipeShowCmd)
recipeDeactivateCmd := makeRecipeDeactivateCmd()
recipeCmd.AddCommand(recipeDeactivateCmd)
recipeActivateCmd := makeRecipeActivateCmd()
recipeCmd.AddCommand(recipeActivateCmd)
return recipeCmd
}

func makeRecipeShowCmd() *cobra.Command {
var recipeShowCmd = &cobra.Command{
Use: "show [RECIPE_NAME]",
Aliases: []string{"get", "describe", "desc"},
Annotations: authNeededAlways,
Args: cobra.ExactArgs(1),
Short: "Show details of a recipe in the current workspace",
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
return cli.RecipeShow(ctx, global.Client, args[0])
},
}
return recipeShowCmd
}

func makeRecipeListCmd() *cobra.Command {
var recipeListCmd = &cobra.Command{
Use: "list",
Aliases: []string{"ls"},
Annotations: authNeededAlways,
Args: cobra.NoArgs,
Short: "List recipes in the current workspace",
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
return cli.RecipeList(ctx, global.Client)
},
}
return recipeListCmd
}

func makeRecipeDeactivateCmd() *cobra.Command {
var recipeArchiveCmd = &cobra.Command{
Use: "deactivate [RECIPE_NAME...]",
Aliases: []string{"remove", "rm", "delete", "del", "disable", "archive"},
Annotations: authNeededAlways,
Args: cobra.MinimumNArgs(1),
Short: "Deactivates a recipe in the current workspace",
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
var errs []error
for _, name := range args {
errs = append(errs, cli.RecipeActivate(ctx, global.Client, name, false))
}
return errors.Join(errs...)
},
}
return recipeArchiveCmd
}

func makeRecipeActivateCmd() *cobra.Command {
var recipeUnarchiveCmd = &cobra.Command{
Use: "activate [RECIPE_NAME...]",
Aliases: []string{"restore", "enable", "undelete", "unarchive"},
Annotations: authNeededAlways,
Args: cobra.MinimumNArgs(1),
Short: "Activates a recipe in the current workspace",
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
var errs []error
for _, name := range args {
errs = append(errs, cli.RecipeActivate(ctx, global.Client, name, true))
}
return errors.Join(errs...)
},
}
return recipeUnarchiveCmd
}
1 change: 0 additions & 1 deletion src/cmd/cli/command/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ func promptForStackParameters(ctx context.Context, params *stacks.Parameters) er
}

*params = *newParams

return nil
}

Expand Down
18 changes: 9 additions & 9 deletions src/cmd/cli/command/stack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,13 @@ func TestStackListCmd(t *testing.T) {
Name: "teststack1",
Provider: client.ProviderAWS,
Region: "us-test-2",
Mode: modes.ModeAffordable,
Mode: modes.RecipeAffordable,
},
{
Name: "teststack2",
Provider: client.ProviderGCP,
Region: "us-central1",
Mode: modes.ModeBalanced,
Mode: modes.RecipeBalanced,
},
},
expectOutput: "NAME DEFAULT PROVIDER REGION ACCOUNT MODE DEPLOYEDAT\n" +
Expand Down Expand Up @@ -165,7 +165,7 @@ func TestStackNewCmd(t *testing.T) {
Name: "teststack",
Provider: client.ProviderAWS,
Region: "us-test-2",
Mode: modes.ModeAffordable,
Mode: modes.RecipeAffordable,
},
existingStacks: []*defangv1.Stack{},
},
Expand All @@ -175,7 +175,7 @@ func TestStackNewCmd(t *testing.T) {
Name: "",
Provider: client.ProviderAWS,
Region: "us-test-2",
Mode: modes.ModeAffordable,
Mode: modes.RecipeAffordable,
},
existingStacks: []*defangv1.Stack{},
expectErr: "invalid stack name",
Expand All @@ -186,7 +186,7 @@ func TestStackNewCmd(t *testing.T) {
Name: "existingstack",
Provider: client.ProviderAWS,
Region: "us-test-2",
Mode: modes.ModeAffordable,
Mode: modes.RecipeAffordable,
},
existingStacks: []*defangv1.Stack{{Name: "existingstack", Project: ""}},
},
Expand All @@ -197,7 +197,7 @@ func TestStackNewCmd(t *testing.T) {
Name: "existingstack",
Provider: client.ProviderAWS,
Region: "us-test-2",
Mode: modes.ModeAffordable,
Mode: modes.RecipeAffordable,
},
existingStacks: []*defangv1.Stack{{Name: "existingstack", Project: ""}},
expectErr: "already exists",
Expand Down Expand Up @@ -238,7 +238,7 @@ func TestLoadStackEnv(t *testing.T) {
parameters: stacks.Parameters{
Provider: client.ProviderAWS,
Region: "us-west-2",
Mode: modes.ModeAffordable,
Mode: modes.RecipeAffordable,
Variables: map[string]string{
"AWS_PROFILE": "default",
},
Expand All @@ -255,7 +255,7 @@ func TestLoadStackEnv(t *testing.T) {
parameters: stacks.Parameters{
Provider: client.ProviderGCP,
Region: "us-central1",
Mode: modes.ModeBalanced,
Mode: modes.RecipeBalanced,
Variables: map[string]string{
"GCP_PROJECT_ID": "my-gcp-project",
"DEFANG_PREFIX": "test",
Expand All @@ -276,7 +276,7 @@ func TestLoadStackEnv(t *testing.T) {
parameters: stacks.Parameters{
Provider: client.ProviderAWS,
Region: "us-west-2",
Mode: modes.ModeAffordable,
Mode: modes.RecipeAffordable,
Variables: map[string]string{
"AWS_PROFILE": "default",
"DEFANG_PREFIX": "test",
Expand Down
7 changes: 1 addition & 6 deletions src/pkg/agent/tools/create_aws_stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,11 @@ type CreateAWSStackParams struct {
}

func HandleCreateAWSStackTool(ctx context.Context, params CreateAWSStackParams, sc StackConfig) (string, error) {
mode, err := modes.Parse(params.Mode)
if err != nil {
return "Invalid mode provided", err
}

newStack := stacks.Parameters{
Name: params.Name,
Region: params.Region,
Provider: client.ProviderAWS,
Mode: mode,
Mode: modes.ParseRecipe(params.Mode),
Comment thread
lionello marked this conversation as resolved.
Variables: map[string]string{
"AWS_PROFILE": params.AWS_Profile,
},
Expand Down
7 changes: 1 addition & 6 deletions src/pkg/agent/tools/create_azure_stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,11 @@ type CreateAzureStackParams struct {
}

func HandleCreateAzureStackTool(ctx context.Context, params CreateAzureStackParams, sc StackConfig) (string, error) {
mode, err := modes.Parse(params.Mode)
if err != nil {
return "Invalid mode provided", err
}

newStack := stacks.Parameters{
Name: params.Name,
Region: params.Location,
Provider: client.ProviderAzure,
Mode: mode,
Mode: modes.ParseRecipe(params.Mode),
Variables: map[string]string{
"AZURE_SUBSCRIPTION_ID": params.AzureSubscriptionID,
},
Expand Down
7 changes: 1 addition & 6 deletions src/pkg/agent/tools/create_gcp_stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,11 @@ type CreateGCPStackParams struct {
}

func HandleCreateGCPStackTool(ctx context.Context, params CreateGCPStackParams, sc StackConfig) (string, error) {
mode, err := modes.Parse(params.Mode)
if err != nil {
return "Invalid mode provided", err
}

newStack := stacks.Parameters{
Name: params.Name,
Region: params.Region,
Provider: client.ProviderGCP,
Mode: mode,
Mode: modes.ParseRecipe(params.Mode),
Variables: map[string]string{
"GCP_PROJECT_ID": params.GCPProjectID,
},
Expand Down
2 changes: 1 addition & 1 deletion src/pkg/agent/tools/current_stack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestHandleCurrentStackTool(t *testing.T) {
Name: "test-stack",
Provider: client.ProviderAWS,
Region: "us-test-2",
Mode: modes.ModeAffordable,
Mode: modes.RecipeAffordable,
Variables: map[string]string{
"AWS_PROFILE": "default",
},
Expand Down
4 changes: 2 additions & 2 deletions src/pkg/agent/tools/default_tool_cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (DefaultToolCLI) ConfigSet(ctx context.Context, projectName string, provide
return err
}

func (DefaultToolCLI) RunEstimate(ctx context.Context, project *compose.Project, fabric *client.GrpcClient, provider client.Provider, providerId client.ProviderID, region string, mode modes.Mode) (*defangv1.EstimateResponse, error) {
func (DefaultToolCLI) RunEstimate(ctx context.Context, project *compose.Project, fabric *client.GrpcClient, provider client.Provider, providerId client.ProviderID, region string, mode modes.Recipe) (*defangv1.EstimateResponse, error) {
return cli.RunEstimate(ctx, project, fabric, provider, providerId, region, mode)
}

Expand Down Expand Up @@ -76,7 +76,7 @@ func (DefaultToolCLI) GetServices(ctx context.Context, projectName string, provi
return cli.GetServices(ctx, projectName, provider)
}

func (DefaultToolCLI) PrintEstimate(mode modes.Mode, estimate *defangv1.EstimateResponse) string {
func (DefaultToolCLI) PrintEstimate(mode modes.Recipe, estimate *defangv1.EstimateResponse) string {
stdout := new(bytes.Buffer)
captureTerm := term.NewTerm(
os.Stdin,
Expand Down
2 changes: 1 addition & 1 deletion src/pkg/agent/tools/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func HandleDeployTool(ctx context.Context, loader client.Loader, params DeployPa
deployResp, project, err := cli.ComposeUp(ctx, client, provider, sc.Stack, cliTypes.ComposeUpParams{
Project: project,
UploadMode: compose.UploadModeDigest,
Mode: modes.ModeAffordable,
Mode: modes.RecipeAffordable,
})
if err != nil {
err = fmt.Errorf("failed to compose up services: %w", err)
Expand Down
10 changes: 3 additions & 7 deletions src/pkg/agent/tools/estimate.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,16 @@ func HandleEstimateTool(ctx context.Context, loader client.Loader, params Estima
return "", err
}

var deploymentMode modes.Mode
err = deploymentMode.Set(params.DeploymentMode)
if err != nil {
return "", err
}
recipe := modes.ParseRecipe(params.DeploymentMode)

term.Debug("Function invoked: cli.RunEstimate")
estimate, err := cli.RunEstimate(ctx, project, fabric, defangProvider, providerID, params.Region, deploymentMode)
estimate, err := cli.RunEstimate(ctx, project, fabric, defangProvider, providerID, params.Region, recipe)
if err != nil {
return "", fmt.Errorf("failed to run estimate: %w", err)
}
term.Debugf("Estimate: %+v", estimate)

estimateText := cli.PrintEstimate(deploymentMode, estimate)
estimateText := cli.PrintEstimate(recipe, estimate)

return "Successfully estimated the cost of the project to " + providerID.Name() + ":\n" + estimateText, nil
}
Loading
Loading