Allow Regions query when listing ECS Services (#51585)

Listing ECS Services requires an AWS Region.
Instead of guessing the AWS Regions, this PR allows the API Client to
send a list of AWS Regions which are used call the ECS APIs
This commit is contained in:
Marco Dinis
2025-01-31 09:02:17 +00:00
committed by GitHub
parent 2f9bd2af8f
commit f18259727d
2 changed files with 73 additions and 1 deletions
+30 -1
View File
@@ -275,7 +275,7 @@ func (h *Handler) awsOIDCListDeployedDatabaseService(w http.ResponseWriter, r *h
return nil, trace.BadParameter("an integration name is required")
}
regions, err := fetchRelevantAWSRegions(ctx, clt, clt.DiscoveryConfigClient())
regions, err := regionsForListingDeployedDatabaseService(ctx, r, clt, clt.DiscoveryConfigClient())
if err != nil {
return nil, trace.Wrap(err)
}
@@ -290,6 +290,35 @@ func (h *Handler) awsOIDCListDeployedDatabaseService(w http.ResponseWriter, r *h
}, nil
}
func extractAWSRegionsFromQuery(r *http.Request) ([]string, error) {
var ret []string
for _, region := range r.URL.Query()["regions"] {
if err := aws.IsValidRegion(region); err != nil {
return nil, trace.BadParameter("invalid region %s", region)
}
ret = append(ret, region)
}
return ret, nil
}
func regionsForListingDeployedDatabaseService(ctx context.Context, r *http.Request, authClient databaseGetter, discoveryConfigsClient discoveryConfigLister) ([]string, error) {
if r.URL.Query().Has("regions") {
regions, err := extractAWSRegionsFromQuery(r)
if err != nil {
return nil, trace.Wrap(err)
}
return regions, err
}
regions, err := fetchRelevantAWSRegions(ctx, authClient, discoveryConfigsClient)
if err != nil {
return nil, trace.Wrap(err)
}
return regions, nil
}
type databaseGetter interface {
GetResources(ctx context.Context, req *proto.ListResourcesRequest) (*proto.ListResourcesResponse, error)
GetDatabases(context.Context) ([]types.Database, error)
+43
View File
@@ -22,6 +22,7 @@ import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"strconv"
"strings"
@@ -1326,6 +1327,48 @@ func dummyDeployedDatabaseServices(count int, command []string) []*integrationv1
return ret
}
func TestRegionsForListingDeployedDatabaseService(t *testing.T) {
ctx := context.Background()
t.Run("regions query param is used instead of parsing internal resources", func(t *testing.T) {
clt := &mockRelevantAWSRegionsClient{
databaseServices: &proto.ListResourcesResponse{
Resources: []*proto.PaginatedResource{},
},
databases: make([]types.Database, 0),
discoveryConfigs: make([]*discoveryconfig.DiscoveryConfig, 0),
}
r := http.Request{
URL: &url.URL{RawQuery: "regions=us-east-1&regions=us-east-2"},
}
gotRegions, err := regionsForListingDeployedDatabaseService(ctx, &r, clt, clt)
require.NoError(t, err)
require.ElementsMatch(t, []string{"us-east-1", "us-east-2"}, gotRegions)
})
t.Run("fallbacks to internal resources when query param is not present", func(t *testing.T) {
clt := &mockRelevantAWSRegionsClient{
databaseServices: &proto.ListResourcesResponse{
Resources: []*proto.PaginatedResource{{Resource: &proto.PaginatedResource_DatabaseService{
DatabaseService: &types.DatabaseServiceV1{Spec: types.DatabaseServiceSpecV1{
ResourceMatchers: []*types.DatabaseResourceMatcher{
{Labels: &types.Labels{"region": []string{"us-east-1"}}},
{Labels: &types.Labels{"region": []string{"us-east-2"}}},
},
}},
}}},
},
databases: make([]types.Database, 0),
discoveryConfigs: make([]*discoveryconfig.DiscoveryConfig, 0),
}
r := http.Request{
URL: &url.URL{},
}
gotRegions, err := regionsForListingDeployedDatabaseService(ctx, &r, clt, clt)
require.NoError(t, err)
require.ElementsMatch(t, []string{"us-east-1", "us-east-2"}, gotRegions)
})
}
func TestFetchRelevantAWSRegions(t *testing.T) {
ctx := context.Background()