From f1d393d6bcb328d07f794bcc437b729509c5f2b2 Mon Sep 17 00:00:00 2001 From: Gavin Frazar Date: Fri, 26 Jul 2024 13:06:30 -0700 Subject: [PATCH] link to ECS service for RDS enrollment The old behavior linked to the ECS cluster dashboard because we were doing potentially multiple deployments. This behavior is maintained, except now if there is only one deployment, which is the nominal case now, then it will link to that deployment's ECS service specifically. --- .../integration/v1/awsoidc_service.pb.go | 3 ++- .../integration/v1/awsoidc_service.proto | 3 ++- .../awsoidc/deploydatabaseservice.go | 26 +++++++++++++++---- .../awsoidc/deploydatabaseservice_test.go | 4 +-- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/api/gen/proto/go/teleport/integration/v1/awsoidc_service.pb.go b/api/gen/proto/go/teleport/integration/v1/awsoidc_service.pb.go index 786bbe9f19097..5eb41fa4fafaa 100644 --- a/api/gen/proto/go/teleport/integration/v1/awsoidc_service.pb.go +++ b/api/gen/proto/go/teleport/integration/v1/awsoidc_service.pb.go @@ -1583,7 +1583,8 @@ type DeployDatabaseServiceResponse struct { // ClusterArn identifies the cluster where the deployment was made. ClusterArn string `protobuf:"bytes,1,opt,name=cluster_arn,json=clusterArn,proto3" json:"cluster_arn,omitempty"` - // ClusterDashboardUrl is the URL for Amazon Web Console that links directly to the Amazon ECS Cluster. + // ClusterDashboardURL is a link to the Amazon ECS cluster dashboard or a + // specific cluster service if a single deployment was requested. ClusterDashboardUrl string `protobuf:"bytes,2,opt,name=cluster_dashboard_url,json=clusterDashboardUrl,proto3" json:"cluster_dashboard_url,omitempty"` } diff --git a/api/proto/teleport/integration/v1/awsoidc_service.proto b/api/proto/teleport/integration/v1/awsoidc_service.proto index 0c0813df5ad7f..583dc68a8fd2b 100644 --- a/api/proto/teleport/integration/v1/awsoidc_service.proto +++ b/api/proto/teleport/integration/v1/awsoidc_service.proto @@ -359,7 +359,8 @@ message DeployDatabaseServiceDeployment { message DeployDatabaseServiceResponse { // ClusterArn identifies the cluster where the deployment was made. string cluster_arn = 1; - // ClusterDashboardUrl is the URL for Amazon Web Console that links directly to the Amazon ECS Cluster. + // ClusterDashboardURL is a link to the Amazon ECS cluster dashboard or a + // specific cluster service if a single deployment was requested. string cluster_dashboard_url = 2; } diff --git a/lib/integrations/awsoidc/deploydatabaseservice.go b/lib/integrations/awsoidc/deploydatabaseservice.go index d6d35ef91585c..457e224882091 100644 --- a/lib/integrations/awsoidc/deploydatabaseservice.go +++ b/lib/integrations/awsoidc/deploydatabaseservice.go @@ -147,7 +147,8 @@ type DeployDatabaseServiceResponse struct { // ClusterARN is the Amazon ECS Cluster ARN where the task was started. ClusterARN string - // ClusterDashboardURL is a link to the Cluster's Dashboard URL in Amazon Console. + // ClusterDashboardURL is a link to the Amazon ECS cluster dashboard or + // a specific cluster service if a single deployment was requested. ClusterDashboardURL string } @@ -214,7 +215,7 @@ func DeployDatabaseService(ctx context.Context, clt DeployServiceClient, req Dep ) log.DebugContext(ctx, "Upsert ECS Cluster") - cluster, err := upsertCluster(ctx, clt, req.ecsClusterName, req.ResourceCreationTags) + ecsCluster, err := upsertCluster(ctx, clt, req.ecsClusterName, req.ResourceCreationTags) if err != nil { return nil, trace.Wrap(err) } @@ -260,11 +261,22 @@ func DeployDatabaseService(ctx context.Context, clt DeployServiceClient, req Dep } return &DeployDatabaseServiceResponse{ - ClusterARN: aws.ToString(cluster.ClusterArn), - ClusterDashboardURL: ecsClusterDashboardURL(req.Region, aws.ToString(cluster.ClusterName)), + ClusterARN: aws.ToString(ecsCluster.ClusterArn), + ClusterDashboardURL: deploymentURL(req.Region, aws.ToString(ecsCluster.ClusterName), req.Deployments), }, nil } +// deploymentURL returns a link to the service in the ECS cluster for a single +// deployment, which is the nominal case since we updated the enrollment flow +// to deploy a single VPC at a time, or a link to the ECS cluster overview +// if multiple deployments are requested. +func deploymentURL(region, ecsClusterName string, deps []DeployDatabaseServiceRequestDeployment) string { + if len(deps) == 1 { + return ecsServiceDashboardURL(region, ecsClusterName, deps[0].VPCID) + } + return ecsClusterDashboardURL(region, ecsClusterName) +} + // ecsTaskName returns the normalized ECS TaskDefinition Family func ecsTaskName(teleportClusterName, deploymentMode, vpcid string) string { return normalizeECSResourceName(fmt.Sprintf("%s-teleport-%s-%s", teleportClusterName, deploymentMode, vpcid)) @@ -294,7 +306,11 @@ func ECSDatabaseServiceDashboardURL(region, teleportClusterName, vpcID string) ( return "", trace.BadParameter("empty VPC ID") } ecsClusterName := normalizeECSClusterName(teleportClusterName) + return ecsServiceDashboardURL(region, ecsClusterName, vpcID), nil +} + +func ecsServiceDashboardURL(region, ecsClusterName, vpcID string) string { ecsClusterDashboard := ecsClusterDashboardURL(region, ecsClusterName) serviceName := ecsServiceName(DatabaseServiceDeploymentMode, vpcID) - return fmt.Sprintf("%s/%s", ecsClusterDashboard, serviceName), nil + return fmt.Sprintf("%s/%s", ecsClusterDashboard, serviceName) } diff --git a/lib/integrations/awsoidc/deploydatabaseservice_test.go b/lib/integrations/awsoidc/deploydatabaseservice_test.go index ec871eaf092ac..96026dcfbbd40 100644 --- a/lib/integrations/awsoidc/deploydatabaseservice_test.go +++ b/lib/integrations/awsoidc/deploydatabaseservice_test.go @@ -439,7 +439,7 @@ func TestDeployDatabaseService(t *testing.T) { }, ) require.NoError(t, err) - require.Equal(t, "https://us-east-1.console.aws.amazon.com/ecs/v2/clusters/cluster-name-teleport/services", resp.ClusterDashboardURL) + require.Equal(t, "https://us-east-1.console.aws.amazon.com/ecs/v2/clusters/cluster-name-teleport/services/database-service-vpc-123", resp.ClusterDashboardURL) require.Equal(t, "ARNcluster-name-teleport", resp.ClusterARN) require.Contains(t, mockClient.clusters, "cluster-name-teleport") require.Contains(t, mockClient.services, "database-service-vpc-123") @@ -550,7 +550,7 @@ func TestDeployDatabaseService(t *testing.T) { }, ) require.NoError(t, err) - require.Equal(t, "https://us-east-1.console.aws.amazon.com/ecs/v2/clusters/cluster-name-teleport/services", resp.ClusterDashboardURL) + require.Equal(t, "https://us-east-1.console.aws.amazon.com/ecs/v2/clusters/cluster-name-teleport/services/database-service-vpc-123", resp.ClusterDashboardURL) require.Equal(t, "ARNcluster-name-teleport", resp.ClusterARN) }) }