Skip to content

Commit 2076860

Browse files
avoid assuming region is us-west-2 when provider is gcp (#1306)
* avoid assuming region is us-west-2 when provider is gcp * allow region to be set through env vars in mcp server * use us-central1 for default gcp region in mcp estimate tool * add support for gcp estimation in mcp server * show an interactive selector if provider is not specified before estimate * create a GetRegion util to get default region for each provider
1 parent 8493cec commit 2076860

File tree

3 files changed

+54
-4
lines changed

3 files changed

+54
-4
lines changed

src/cmd/cli/command/estimate.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package command
33
import (
44
"fmt"
55

6-
"github.com/DefangLabs/defang/src/pkg"
76
"github.com/DefangLabs/defang/src/pkg/cli"
87
cliClient "github.com/DefangLabs/defang/src/pkg/cli/client"
98
"github.com/DefangLabs/defang/src/pkg/term"
@@ -27,12 +26,25 @@ func makeEstimateCmd() *cobra.Command {
2726
return err
2827
}
2928

29+
if providerID == cliClient.ProviderAuto {
30+
_, err = interactiveSelectProvider([]cliClient.ProviderID{
31+
cliClient.ProviderAWS,
32+
cliClient.ProviderGCP,
33+
})
34+
if err != nil {
35+
return fmt.Errorf("failed to select provider: %w", err)
36+
}
37+
}
38+
3039
var previewProvider cliClient.Provider = &cliClient.PlaygroundProvider{FabricClient: client}
3140

3241
// default to development mode if not specified; TODO: when mode is not specified, show an interactive prompt
3342
if mode.Value() == defangv1.DeploymentMode_MODE_UNSPECIFIED {
3443
mode = Mode(defangv1.DeploymentMode_DEVELOPMENT)
3544
}
45+
if region == "" {
46+
region = cliClient.GetRegion(providerID) // This sets the default region based on the provider
47+
}
3648

3749
estimate, err := cli.RunEstimate(ctx, project, client, previewProvider, providerID, region, mode.Value())
3850
if err != nil {
@@ -47,6 +59,6 @@ func makeEstimateCmd() *cobra.Command {
4759
}
4860

4961
estimateCmd.Flags().VarP(&mode, "mode", "m", fmt.Sprintf("deployment mode; one of %v", allModes()))
50-
estimateCmd.Flags().StringP("region", "r", pkg.Getenv("AWS_REGION", "us-west-2"), "which cloud region to estimate")
62+
estimateCmd.Flags().StringP("region", "r", "", "which cloud region to estimate")
5163
return estimateCmd
5264
}

src/pkg/cli/client/region.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package client
2+
3+
import "github.com/DefangLabs/defang/src/pkg"
4+
5+
func GetRegion(provider ProviderID) string {
6+
switch provider {
7+
case ProviderAWS:
8+
return pkg.Getenv("AWS_REGION", "us-west-2") // Default region for AWS
9+
case ProviderGCP:
10+
return pkg.Getenv("CLOUDSDK_COMPUTE_REGION", "us-central1") // Default region for GCP
11+
case ProviderDO:
12+
return pkg.Getenv("DO_REGION", "nyc3") // Default region for DigitalOcean
13+
default:
14+
return "" // No default region for unsupported providers
15+
}
16+
}

src/pkg/mcp/tools/estimate.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ func setupEstimateTool(s *server.MCPServer, cluster string) {
2626
mcp.Description("Path to current working directory"),
2727
),
2828

29+
mcp.WithString("provider",
30+
mcp.Description("The cloud provider to estimate costs for. Supported options are AWS or GCP"),
31+
mcp.DefaultString("AWS"),
32+
mcp.Enum("AWS", "GCP"),
33+
),
34+
2935
mcp.WithString("deployment_mode",
3036
mcp.Description("The deployment mode for the estimate. Options are AFFORDABLE, BALANCED or HIGH AVAILABILITY."),
3137
mcp.DefaultString("AFFORDABLE"),
@@ -53,6 +59,11 @@ func setupEstimateTool(s *server.MCPServer, cluster string) {
5359
modeString = "AFFORDABLE" // Default to AFFORDABLE if not provided
5460
}
5561

62+
providerString, ok := request.Params.Arguments["provider"].(string)
63+
if !ok {
64+
providerString = "aws" // Default to AWS if not provided
65+
}
66+
5667
// This logic is replicated from src/cmd/cli/command/mode.go
5768
// I couldn't figure out how to import it without circular dependencies
5869
modeString = strings.ToUpper(modeString)
@@ -89,10 +100,21 @@ func setupEstimateTool(s *server.MCPServer, cluster string) {
89100
}
90101

91102
defangProvider := &cliClient.PlaygroundProvider{FabricClient: client}
92-
providerID := cliClient.ProviderAWS // Default to AWS
103+
104+
var providerID cliClient.ProviderID
105+
err = providerID.Set(providerString)
106+
if err != nil {
107+
term.Error("Invalid provider specified", "error", err)
108+
return mcp.NewToolResultErrorFromErr("Invalid provider specified", err), nil
109+
}
93110

94111
term.Debug("Function invoked: cli.RunEstimate")
95-
estimate, err := cli.RunEstimate(ctx, project, client, defangProvider, providerID, "us-west-2", mode)
112+
var region string
113+
if region == "" {
114+
region = cliClient.GetRegion(providerID) // This sets the default region based on the provider
115+
}
116+
117+
estimate, err := cli.RunEstimate(ctx, project, client, defangProvider, providerID, region, mode)
96118
if err != nil {
97119
return mcp.NewToolResultErrorFromErr("Failed to run estimate", err), nil
98120
}

0 commit comments

Comments
 (0)