`ps` shows LoadBalancer URL

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2020-07-03 11:07:08 +02:00
parent 324443deb6
commit f892ee1004
No known key found for this signature in database
GPG Key ID: 9858809D6F8F6E7E
5 changed files with 71 additions and 31 deletions

View File

@ -14,7 +14,31 @@ func (b *Backend) Ps(ctx context.Context, project *types.Project) ([]compose.Ser
cluster = project.Name
}
status, err := b.api.DescribeServices(ctx, cluster, project.Name)
resources, err := b.api.ListStackResources(ctx, project.Name)
if err != nil {
return nil, err
}
var loadBalancer string
if lb, ok := project.Extensions[compose.ExtensionLB]; ok {
loadBalancer = lb.(string)
}
servicesARN := []string{}
for _, r := range resources {
switch r.Type {
case "AWS::ECS::Service":
servicesARN = append(servicesARN, r.ARN)
case "AWS::ElasticLoadBalancingV2::LoadBalancer":
loadBalancer = r.ARN
}
}
status, err := b.api.DescribeServices(ctx, cluster, servicesARN)
if err != nil {
return nil, err
}
url, err := b.api.GetLoadBalancerURL(ctx, loadBalancer)
if err != nil {
return nil, err
}
@ -26,7 +50,7 @@ func (b *Backend) Ps(ctx context.Context, project *types.Project) ([]compose.Ser
}
ports := []string{}
for _, p := range s.Ports {
ports = append(ports, fmt.Sprintf("*:%d->%d/%s", p.Published, p.Target, p.Protocol))
ports = append(ports, fmt.Sprintf("%s:%d->%d/%s", url, p.Published, p.Target, p.Protocol))
}
state.Ports = ports
status[i] = state

View File

@ -105,7 +105,6 @@ func (b Backend) GetLoadBalancer(ctx context.Context, project *types.Project) (s
if !ok {
return "", fmt.Errorf("Load Balancer does not exist: %s", lb)
}
return b.api.GetLoadBalancerARN(ctx, lbName)
}
return "", nil
}

View File

@ -16,13 +16,15 @@ type API interface {
StackExists(ctx context.Context, name string) (bool, error)
CreateStack(ctx context.Context, name string, template *cloudformation.Template, parameters map[string]string) error
DeleteStack(ctx context.Context, name string) error
DescribeServices(ctx context.Context, cluster string, project string) ([]compose.ServiceStatus, error)
ListStackResources(ctx context.Context, name string) ([]compose.StackResource, error)
GetStackID(ctx context.Context, name string) (string, error)
WaitStackComplete(ctx context.Context, name string, operation int) error
DescribeStackEvents(ctx context.Context, stackID string) ([]*cf.StackEvent, error)
LoadBalancerExists(ctx context.Context, name string) (bool, error)
GetLoadBalancerARN(ctx context.Context, name string) (string, error)
DescribeServices(ctx context.Context, cluster string, arns []string) ([]compose.ServiceStatus, error)
LoadBalancerExists(ctx context.Context, arn string) (bool, error)
GetLoadBalancerURL(ctx context.Context, arn string) (string, error)
ClusterExists(ctx context.Context, name string) (bool, error)

View File

@ -222,6 +222,27 @@ func (s sdk) DescribeStackEvents(ctx context.Context, stackID string) ([]*cloudf
}
}
func (s sdk) ListStackResources(ctx context.Context, name string) ([]compose.StackResource, error) {
// FIXME handle pagination
res, err := s.CF.ListStackResourcesWithContext(ctx, &cloudformation.ListStackResourcesInput{
StackName: aws.String(name),
})
if err != nil {
return nil, err
}
resources := []compose.StackResource{}
for _, r := range res.StackResourceSummaries {
resources = append(resources, compose.StackResource{
LogicalID: *r.LogicalResourceId,
Type: *r.ResourceType,
ARN: *r.PhysicalResourceId,
Status: *r.ResourceStatus,
})
}
return resources, nil
}
func (s sdk) DeleteStack(ctx context.Context, name string) error {
logrus.Debug("Delete CloudFormation stack")
_, err := s.CF.DeleteStackWithContext(ctx, &cloudformation.DeleteStackInput{
@ -270,7 +291,6 @@ func (s sdk) InspectSecret(ctx context.Context, id string) (compose.Secret, erro
}
func (s sdk) ListSecrets(ctx context.Context) ([]compose.Secret, error) {
logrus.Debug("List secrets ...")
response, err := s.SM.ListSecrets(&secretsmanager.ListSecretsInput{})
if err != nil {
@ -336,18 +356,10 @@ func (s sdk) GetLogs(ctx context.Context, name string, consumer compose.LogConsu
}
}
func (s sdk) DescribeServices(ctx context.Context, cluster string, project string) ([]compose.ServiceStatus, error) {
// TODO handle pagination
list, err := s.ECS.ListServicesWithContext(ctx, &ecs.ListServicesInput{
Cluster: aws.String(cluster),
})
if err != nil {
return nil, err
}
func (s sdk) DescribeServices(ctx context.Context, cluster string, arns []string) ([]compose.ServiceStatus, error) {
services, err := s.ECS.DescribeServicesWithContext(ctx, &ecs.DescribeServicesInput{
Cluster: aws.String(cluster),
Services: list.ServiceArns,
Services: aws.StringSlice(arns),
Include: aws.StringSlice([]string{"TAGS"}),
})
if err != nil {
@ -356,17 +368,13 @@ func (s sdk) DescribeServices(ctx context.Context, cluster string, project strin
status := []compose.ServiceStatus{}
for _, service := range services.Services {
var name string
var stack string
for _, t := range service.Tags {
switch *t.Key {
case compose.ProjectTag:
stack = *t.Value
case compose.ServiceTag:
if *t.Key == compose.ServiceTag {
name = *t.Value
}
}
if stack != project {
continue
if name == "" {
return nil, fmt.Errorf("service %s doesn't have a %s tag", *service.ServiceArn, compose.ServiceTag)
}
status = append(status, compose.ServiceStatus{
ID: *service.ServiceName,
@ -410,10 +418,10 @@ func (s sdk) GetPublicIPs(ctx context.Context, interfaces ...string) (map[string
return publicIPs, nil
}
func (s sdk) LoadBalancerExists(ctx context.Context, name string) (bool, error) {
logrus.Debug("Check if cluster was already created: ", name)
func (s sdk) LoadBalancerExists(ctx context.Context, arn string) (bool, error) {
logrus.Debug("Check if LoadBalancer exists: ", arn)
lbs, err := s.ELB.DescribeLoadBalancersWithContext(ctx, &elbv2.DescribeLoadBalancersInput{
Names: []*string{aws.String(name)},
LoadBalancerArns: []*string{aws.String(arn)},
})
if err != nil {
return false, err
@ -421,13 +429,13 @@ func (s sdk) LoadBalancerExists(ctx context.Context, name string) (bool, error)
return len(lbs.LoadBalancers) > 0, nil
}
func (s sdk) GetLoadBalancerARN(ctx context.Context, name string) (string, error) {
logrus.Debug("Check if cluster was already created: ", name)
func (s sdk) GetLoadBalancerURL(ctx context.Context, arn string) (string, error) {
logrus.Debug("Retrieve load balancer URL: ", arn)
lbs, err := s.ELB.DescribeLoadBalancersWithContext(ctx, &elbv2.DescribeLoadBalancersInput{
Names: []*string{aws.String(name)},
LoadBalancerArns: []*string{aws.String(arn)},
})
if err != nil {
return "", err
}
return *lbs.LoadBalancers[0].LoadBalancerArn, nil
return *lbs.LoadBalancers[0].DNSName, nil
}

View File

@ -2,6 +2,13 @@ package compose
import "encoding/json"
type StackResource struct {
LogicalID string
Type string
ARN string
Status string
}
type ServiceStatus struct {
ID string
Name string