Skip to content

Commit

Permalink
Adds tcld account list-regions command
Browse files Browse the repository at this point in the history
  • Loading branch information
mastermanu authored Sep 18, 2023
1 parent 649f0d4 commit fffdb15
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 30 deletions.
43 changes: 43 additions & 0 deletions app/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"sort"

"github.com/temporalio/tcld/protogen/api/account/v1"
"github.com/temporalio/tcld/protogen/api/accountservice/v1"
Expand All @@ -16,6 +17,11 @@ type AccountClient struct {
ctx context.Context
}

type regionInfo struct {
CloudProviderRegion string
CloudProvider string
}

func NewAccountClient(ctx context.Context, conn *grpc.ClientConn) *AccountClient {
return &AccountClient{
client: accountservice.NewAccountServiceClient(conn),
Expand Down Expand Up @@ -47,6 +53,31 @@ func (c *AccountClient) getAccount() (*account.Account, error) {
return res.Account, nil
}

func (c *AccountClient) listRegions() ([]regionInfo, error) {
resp, err := c.client.GetRegions(c.ctx, &accountservice.GetRegionsRequest{})
if err != nil {
return nil, fmt.Errorf("unable to get regions: %w", err)
}

var regions []regionInfo
for _, r := range resp.Regions {
regions = append(regions, regionInfo{
CloudProviderRegion: r.GetName(),
CloudProvider: r.GetCloudProvider(),
})
}

sort.SliceStable(regions, func(i, j int) bool {
if regions[i].CloudProvider < regions[j].CloudProvider {
return true
}

return regions[i].CloudProviderRegion < regions[j].CloudProviderRegion
})

return regions, nil
}

func (c *AccountClient) updateAccount(ctx *cli.Context, a *account.Account) error {
resourceVersion := a.ResourceVersion
if v := ctx.String(ResourceVersionFlagName); v != "" {
Expand Down Expand Up @@ -107,6 +138,18 @@ func NewAccountCommand(getAccountClientFn GetAccountClientFn) (CommandOut, error
return PrintProto(n)
},
},
{
Name: "list-regions",
Usage: "Lists all regions where the account can provision namespaces",
Aliases: []string{"l"},
Action: func(ctx *cli.Context) error {
regionInfos, err := c.listRegions()
if err != nil {
return err
}
return PrintObj(regionInfos)
},
},
{
Name: "metrics",
Usage: "Configures the metrics endpoint for the Temporal Cloud Account",
Expand Down
13 changes: 13 additions & 0 deletions app/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/stretchr/testify/suite"
"github.com/temporalio/tcld/protogen/api/account/v1"
"github.com/temporalio/tcld/protogen/api/accountservice/v1"
"github.com/temporalio/tcld/protogen/api/common/v1"
"github.com/temporalio/tcld/protogen/api/request/v1"
accountservicemock "github.com/temporalio/tcld/protogen/apimock/accountservice/v1"
"github.com/urfave/cli/v2"
Expand Down Expand Up @@ -72,6 +73,18 @@ func (s *AccountTestSuite) TestGet() {
s.NoError(s.RunCmd("account", "get"))
}

func (s *AccountTestSuite) TestListRegions() {
s.mockService.EXPECT().GetRegions(gomock.Any(), gomock.Any()).Return(nil, errors.New("some error")).Times(1)
s.Error(s.RunCmd("account", "list-regions"))

s.mockService.EXPECT().GetRegions(gomock.Any(), gomock.Any()).Return(&accountservice.GetRegionsResponse{
Regions: []*common.Region{
{CloudProvider: "aws", Name: "us-west-2"},
},
}, nil).Times(1)
s.NoError(s.RunCmd("account", "list-regions"))
}

func (s *AccountTestSuite) TestEnable() {
type morphGetResp func(*accountservice.GetAccountResponse)
type morphUpdateReq func(*accountservice.UpdateAccountRequest)
Expand Down
33 changes: 3 additions & 30 deletions app/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,7 @@ var (
Usage: "The fingerprint of to the ca certificate",
Aliases: []string{"fp"},
}
namespaceRegions = []string{
"ap-northeast-1",
"ap-south-1",
"ap-southeast-1",
"ap-southeast-2",
"ca-central-1",
"eu-central-1",
"eu-west-1",
"eu-west-2",
"sa-east-1",
"us-east-1",
"us-east-2",
"us-west-2",
}

sinkNameFlag = &cli.StringFlag{
Name: "sink-name",
Usage: "Provide a name for the export sink",
Expand Down Expand Up @@ -407,7 +394,7 @@ func NewNamespaceCommand(getNamespaceClientFn GetNamespaceClientFn) (CommandOut,
},
&cli.StringFlag{
Name: namespaceRegionFlagName,
Usage: fmt.Sprintf("Create namespace in this region; valid regions are: %v", namespaceRegions),
Usage: "Create namespace in specified region; see 'tcld account list-regions' to get a list of available regions for your account",
Aliases: []string{"re"},
Required: true,
},
Expand Down Expand Up @@ -449,13 +436,8 @@ func NewNamespaceCommand(getNamespaceClientFn GetNamespaceClientFn) (CommandOut,
Namespace: ctx.String(NamespaceFlagName),
}

// region (required)
region := ctx.String(namespaceRegionFlagName)
if err := validateNamespaceRegion(region); err != nil {
return err
}
n.Spec = &namespace.NamespaceSpec{
Region: region,
Region: ctx.String(namespaceRegionFlagName),
}

// certs (required)
Expand Down Expand Up @@ -1454,12 +1436,3 @@ func compareCodecSpec(existing, replacement *namespace.CodecServerPropertySpec)

return diff.Diff(string(existingBytes), string(replacementBytes)), nil
}

func validateNamespaceRegion(region string) error {
for _, r := range namespaceRegions {
if r == region {
return nil
}
}
return fmt.Errorf("namespace region: %s not allowed", region)
}

0 comments on commit fffdb15

Please sign in to comment.