diff --git a/VERSION b/VERSION index 589268e..6261a05 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.0 \ No newline at end of file +1.3.1 \ No newline at end of file diff --git a/aws/elb/client.go b/aws/elb/client.go index ea400f0..33646d1 100644 --- a/aws/elb/client.go +++ b/aws/elb/client.go @@ -42,7 +42,30 @@ func (c *Client) CreateLoadBalancer(elbName string, internetFacing bool, securit return res.LoadBalancers[0], nil } -func (c *Client) RetrieveLoadBalancer(elbName string) (*_elb.LoadBalancer, error) { +func (c *Client) RetrieveLoadBalancer(elbARN string) (*_elb.LoadBalancer, error) { + params := &_elb.DescribeLoadBalancersInput{ + LoadBalancerArns: _aws.StringSlice([]string{elbARN}), + } + res, err := c.svc.DescribeLoadBalancers(params) + if err != nil { + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "LoadBalancerNotFound" { + return nil, nil + } + } + return nil, err + } + + if len(res.LoadBalancers) == 0 { + return nil, nil + } else if len(res.LoadBalancers) == 1 { + return res.LoadBalancers[0], nil + } + + return nil, fmt.Errorf("Invalid result: %v", res.LoadBalancers) +} + +func (c *Client) RetrieveLoadBalancerByName(elbName string) (*_elb.LoadBalancer, error) { params := &_elb.DescribeLoadBalancersInput{ Names: _aws.StringSlice([]string{elbName}), } diff --git a/commands/delete/command.go b/commands/delete/command.go index c7a8ab8..b66c111 100644 --- a/commands/delete/command.go +++ b/commands/delete/command.go @@ -72,7 +72,7 @@ func (c *Command) Run() error { // ELB Load Balancer elbLoadBalancerName := conv.S(conf.AWS.ELBLoadBalancerName) - elbLoadBalancer, err := c.awsClient.ELB().RetrieveLoadBalancer(elbLoadBalancerName) + elbLoadBalancer, err := c.awsClient.ELB().RetrieveLoadBalancerByName(elbLoadBalancerName) if err != nil { return console.ExitWithErrorString("Failed to retrieve ELB Load Balancer [%s]: %s", elbLoadBalancerName, err.Error()) } diff --git a/commands/deploy/aws_elb.go b/commands/deploy/aws_elb.go index 38f4219..7443ec8 100644 --- a/commands/deploy/aws_elb.go +++ b/commands/deploy/aws_elb.go @@ -24,7 +24,7 @@ func (c *Command) prepareELBLoadBalancer(ecsServiceRoleName, ecsTaskContainerNam } // Check if specified ELB Load Balancer exists or not. - elbLoadBalancer, err := c.awsClient.ELB().RetrieveLoadBalancer(elbLoadBalancerName) + elbLoadBalancer, err := c.awsClient.ELB().RetrieveLoadBalancerByName(elbLoadBalancerName) if err != nil { return nil, fmt.Errorf("Failed to retrieve ELB Load Balancer [%s]: %s", elbLoadBalancerName, err.Error()) } diff --git a/commands/status/command.go b/commands/status/command.go index a703675..de255c3 100644 --- a/commands/status/command.go +++ b/commands/status/command.go @@ -72,173 +72,200 @@ func (c *Command) Run() error { // ECS console.Info("ECS") - { - // ECS cluster - ecsClusterName := core.DefaultECSClusterName(clusterName) - ecsCluster, err := c.awsClient.ECS().RetrieveCluster(ecsClusterName) - if err != nil { - return console.ExitWithErrorString("Failed to retrieve ECS Cluster [%s]: %s", ecsClusterName, err.Error()) - } - if ecsCluster == nil || conv.S(ecsCluster.Status) != "ACTIVE" { - console.DetailWithResourceNote("ECS Cluster", ecsClusterName, "(not found)", true) - ecsCluster = nil - } else { - console.DetailWithResource("ECS Cluster", ecsClusterName) - } - // ECS Task Definition - ecsTaskDefinitionName := core.DefaultECSTaskDefinitionName(appName) - ecsTaskDefinition, err := c.awsClient.ECS().RetrieveTaskDefinition(ecsTaskDefinitionName) - if err != nil { - return console.ExitWithErrorString("Failed to retrieve ECS Task Definition [%s]: %s", ecsTaskDefinitionName, err.Error()) - } - if ecsTaskDefinition == nil { - console.DetailWithResourceNote("ECS Task Definition", ecsTaskDefinitionName, "(not found)", true) - } else { - console.DetailWithResource("ECS Task Definition", - fmt.Sprintf("%s:%d", conv.S(ecsTaskDefinition.Family), conv.I64(ecsTaskDefinition.Revision))) - } + // ECS cluster + ecsClusterName := core.DefaultECSClusterName(clusterName) + ecsCluster, err := c.awsClient.ECS().RetrieveCluster(ecsClusterName) + if err != nil { + return console.ExitWithErrorString("Failed to retrieve ECS Cluster [%s]: %s", ecsClusterName, err.Error()) + } + if ecsCluster == nil || conv.S(ecsCluster.Status) != "ACTIVE" { + console.DetailWithResourceNote("ECS Cluster", ecsClusterName, "(not found)", true) + return nil // stop here + } else { + console.DetailWithResource("ECS Cluster", ecsClusterName) + } - // ECS Service - ecsServiceActive := false - ecsServiceName := core.DefaultECSServiceName(appName) - if ecsCluster != nil { - ecsService, err := c.awsClient.ECS().RetrieveService(ecsClusterName, ecsServiceName) - if err != nil { - return console.ExitWithErrorString("Failed to retrieve ECS Service [%s]: %s", ecsServiceName, err.Error()) - } - if ecsService == nil { - console.DetailWithResourceNote("ECS Service", ecsServiceName, "(not found)", true) - } else if conv.S(ecsService.Status) == "ACTIVE" { - ecsServiceActive = true - console.DetailWithResource("ECS Service", ecsServiceName) - } else { - console.DetailWithResourceNote("ECS Service", ecsServiceName, fmt.Sprintf("(%s)", conv.S(ecsService.Status)), true) - ecsService = nil + // ECS Service + ecsServiceName := core.DefaultECSServiceName(appName) + ecsService, err := c.awsClient.ECS().RetrieveService(ecsClusterName, ecsServiceName) + if err != nil { + return console.ExitWithErrorString("Failed to retrieve ECS Service [%s]: %s", ecsServiceName, err.Error()) + } + if ecsService == nil { + console.DetailWithResourceNote("ECS Service", ecsServiceName, "(not found)", true) + return nil // stop here + } else if conv.S(ecsService.Status) == "ACTIVE" { + console.DetailWithResource("ECS Service", ecsServiceName) + } else { + console.DetailWithResourceNote("ECS Service", ecsServiceName, fmt.Sprintf("(%s)", conv.S(ecsService.Status)), true) + return nil // stop here + } + + // ECS Task Definition + ecsTaskDefinitionName := conv.S(ecsService.TaskDefinition) + ecsTaskDefinition, err := c.awsClient.ECS().RetrieveTaskDefinition(ecsTaskDefinitionName) + if err != nil { + return console.ExitWithErrorString("Failed to retrieve ECS Task Definition [%s]: %s", ecsTaskDefinitionName, err.Error()) + } + if ecsTaskDefinition == nil { + console.DetailWithResourceNote("ECS Task Definition", ecsTaskDefinitionName, "(not found)", true) + return nil // stop here + } else { + console.DetailWithResource("ECS Task Definition", + fmt.Sprintf("%s:%d", conv.S(ecsTaskDefinition.Family), conv.I64(ecsTaskDefinition.Revision))) + } + + // Tasks count / status + isDeploying := false + if ecsService.Deployments != nil { + for _, d := range ecsService.Deployments { + switch conv.S(d.Status) { + case "ACTIVE": + isDeploying = true + case "PRIMARY": } + } + } + if isDeploying { + console.DetailWithResourceNote("Tasks (current/desired/pending)", fmt.Sprintf("%d/%d/%d", + conv.I64(ecsService.RunningCount), + conv.I64(ecsService.DesiredCount), + conv.I64(ecsService.PendingCount)), + "(deploying)", true) + } else { + console.DetailWithResource("Tasks (current/desired/pending)", fmt.Sprintf("%d/%d/%d", + conv.I64(ecsService.RunningCount), + conv.I64(ecsService.DesiredCount), + conv.I64(ecsService.PendingCount))) + } - // ECS Service Details - if ecsService != nil { - for _, lb := range ecsService.LoadBalancers { - elbTargetGroup, err := c.awsClient.ELB().RetrieveTargetGroup(conv.S(lb.TargetGroupArn)) - if err != nil { - return console.ExitWithErrorString("Failed to retrieve ELB Target Group [%s]: %s", conv.S(lb.TargetGroupArn), err.Error()) - } + // Container Definition + for _, containerDefinition := range ecsTaskDefinition.ContainerDefinitions { + console.Info("Container Definition") - console.DetailWithResource("ELB Target Group", fmt.Sprintf("%s:%d", - conv.S(elbTargetGroup.TargetGroupName), - conv.I64(lb.ContainerPort))) - } + console.DetailWithResource("Name", conv.S(containerDefinition.Name)) + console.DetailWithResource("Image", conv.S(containerDefinition.Image)) - isDeploying := false - if ecsService.Deployments != nil { - for _, d := range ecsService.Deployments { - switch conv.S(d.Status) { - case "ACTIVE": - isDeploying = true - case "PRIMARY": - } - } - } + cpu := float64(conv.I64(containerDefinition.Cpu)) / 1024.0 + console.DetailWithResource("CPU", fmt.Sprintf("%.2f", cpu)) - if isDeploying { - console.DetailWithResourceNote("Tasks (current/desired/pending)", fmt.Sprintf("%d/%d/%d", - conv.I64(ecsService.RunningCount), - conv.I64(ecsService.DesiredCount), - conv.I64(ecsService.PendingCount)), - "(deploying)", true) - } else { - console.DetailWithResource("Tasks (current/desired/pending)", fmt.Sprintf("%d/%d/%d", - conv.I64(ecsService.RunningCount), - conv.I64(ecsService.DesiredCount), - conv.I64(ecsService.PendingCount))) - } - } + memory := conv.I64(containerDefinition.Memory) + console.DetailWithResource("Memory", fmt.Sprintf("%dm", memory)) + + for _, pm := range containerDefinition.PortMappings { + console.DetailWithResource("Port Mapping (protocol:container:host)", fmt.Sprintf("%s:%d:%d", + conv.S(pm.Protocol), conv.I64(pm.ContainerPort), conv.I64(pm.HostPort))) } - // Container Definition - if ecsServiceActive && ecsTaskDefinition != nil { - for _, containerDefinition := range ecsTaskDefinition.ContainerDefinitions { - console.Info("Container Definition") + for _, ev := range containerDefinition.Environment { + console.DetailWithResource("Env", fmt.Sprintf("%s=%s", + conv.S(ev.Name), conv.S(ev.Value))) + } + } + + // Tasks + taskARNs, err := c.awsClient.ECS().ListServiceTaskARNs(ecsClusterName, ecsServiceName) + if err != nil { + return console.ExitWithErrorString("Failed to list ECS Tasks for ECS Service [%s]: %s", ecsServiceName, err.Error()) + } + tasks, err := c.awsClient.ECS().RetrieveTasks(ecsClusterName, taskARNs) + if err != nil { + return console.ExitWithErrorString("Failed to retrieve ECS Tasks for ECS Service [%s]: %s", ecsServiceName, err.Error()) + } + + // retrieve container instance info + containerInstanceARNs := []string{} + for _, task := range tasks { + containerInstanceARNs = append(containerInstanceARNs, conv.S(task.ContainerInstanceArn)) + } + containerInstances, err := c.awsClient.ECS().RetrieveContainerInstances(ecsClusterName, containerInstanceARNs) + if err != nil { + return console.ExitWithErrorString("Failed to retrieve ECS Container Instances: %s", err.Error()) + } - console.DetailWithResource("Name", conv.S(containerDefinition.Name)) - console.DetailWithResource("Image", conv.S(containerDefinition.Image)) + // retrieve EC2 Instance info + ec2InstanceIDs := []string{} + for _, ci := range containerInstances { + ec2InstanceIDs = append(ec2InstanceIDs, conv.S(ci.Ec2InstanceId)) + } + ec2Instances, err := c.awsClient.EC2().RetrieveInstances(ec2InstanceIDs) + if err != nil { + return console.ExitWithErrorString("Failed to retrieve EC2 Instances: %s", err.Error()) + } - cpu := float64(conv.I64(containerDefinition.Cpu)) / 1024.0 - console.DetailWithResource("CPU", fmt.Sprintf("%.2f", cpu)) + for _, task := range tasks { + console.Info("ECS Task") - memory := conv.I64(containerDefinition.Memory) - console.DetailWithResource("Memory", fmt.Sprintf("%dm", memory)) + taskDefinition := aws.GetECSTaskDefinitionFamilyAndRevisionFromARN(conv.S(task.TaskDefinitionArn)) + console.DetailWithResource("Task Definition", taskDefinition) - for _, pm := range containerDefinition.PortMappings { - console.DetailWithResource("Port Mapping (protocol:container:host)", fmt.Sprintf("%s:%d:%d", - conv.S(pm.Protocol), conv.I64(pm.ContainerPort), conv.I64(pm.HostPort))) - } + console.DetailWithResource("Status (current/desired)", fmt.Sprintf("%s/%s", + conv.S(task.LastStatus), conv.S(task.DesiredStatus))) - for _, ev := range containerDefinition.Environment { - console.DetailWithResource("Env", fmt.Sprintf("%s=%s", - conv.S(ev.Name), conv.S(ev.Value))) + for _, ci := range containerInstances { + if conv.S(task.ContainerInstanceArn) == conv.S(ci.ContainerInstanceArn) { + console.DetailWithResource("EC2 Instance ID", conv.S(ci.Ec2InstanceId)) + + for _, ec2Instance := range ec2Instances { + if conv.S(ci.Ec2InstanceId) == conv.S(ec2Instance.InstanceId) { + if !utils.IsBlank(conv.S(ec2Instance.PrivateIpAddress)) { + console.DetailWithResource(" Private IP", conv.S(ec2Instance.PrivateIpAddress)) + } + if !utils.IsBlank(conv.S(ec2Instance.PublicIpAddress)) { + console.DetailWithResource(" Public IP", conv.S(ec2Instance.PublicIpAddress)) + } + break + } } + break } } + } - // Tasks - if ecsServiceActive { - // retrieve ECS tasks info - taskARNs, err := c.awsClient.ECS().ListServiceTaskARNs(ecsClusterName, ecsServiceName) - if err != nil { - return console.ExitWithErrorString("Failed to list ECS Tasks for ECS Service [%s]: %s", ecsServiceName, err.Error()) - } - tasks, err := c.awsClient.ECS().RetrieveTasks(ecsClusterName, taskARNs) - if err != nil { - return console.ExitWithErrorString("Failed to retrieve ECS Tasks for ECS Service [%s]: %s", ecsServiceName, err.Error()) - } + // Load Balancer + if ecsService.LoadBalancers != nil && len(ecsService.LoadBalancers) > 0 { + for _, lb := range ecsService.LoadBalancers { + console.Info("Load Balancer") - // retrieve container instance info - containerInstanceARNs := []string{} - for _, task := range tasks { - containerInstanceARNs = append(containerInstanceARNs, conv.S(task.ContainerInstanceArn)) - } - containerInstances, err := c.awsClient.ECS().RetrieveContainerInstances(ecsClusterName, containerInstanceARNs) + elbTargetGroup, err := c.awsClient.ELB().RetrieveTargetGroup(conv.S(lb.TargetGroupArn)) if err != nil { - return console.ExitWithErrorString("Failed to retrieve ECS Container Instances: %s", err.Error()) + return console.ExitWithErrorString("Failed to retrieve ELB Target Group [%s]: %s", conv.S(lb.TargetGroupArn), err.Error()) } - // retrieve EC2 Instance info - ec2InstanceIDs := []string{} - for _, ci := range containerInstances { - ec2InstanceIDs = append(ec2InstanceIDs, conv.S(ci.Ec2InstanceId)) - } - ec2Instances, err := c.awsClient.EC2().RetrieveInstances(ec2InstanceIDs) - if err != nil { - return console.ExitWithErrorString("Failed to retrieve EC2 Instances: %s", err.Error()) - } + console.DetailWithResource("Container Port", fmt.Sprintf("%d", conv.I64(lb.ContainerPort))) + console.DetailWithResource("ELB Target Group", conv.S(elbTargetGroup.TargetGroupName)) - for _, task := range tasks { - console.Info("ECS Task") - - taskDefinition := aws.GetECSTaskDefinitionFamilyAndRevisionFromARN(conv.S(task.TaskDefinitionArn)) - console.DetailWithResource("Task Definition", taskDefinition) - - console.DetailWithResource("Status (current/desired)", fmt.Sprintf("%s/%s", - conv.S(task.LastStatus), conv.S(task.DesiredStatus))) - - for _, ci := range containerInstances { - if conv.S(task.ContainerInstanceArn) == conv.S(ci.ContainerInstanceArn) { - console.DetailWithResource("EC2 Instance ID", conv.S(ci.Ec2InstanceId)) - - for _, ec2Instance := range ec2Instances { - if conv.S(ci.Ec2InstanceId) == conv.S(ec2Instance.InstanceId) { - if !utils.IsBlank(conv.S(ec2Instance.PrivateIpAddress)) { - console.DetailWithResource(" Private IP", conv.S(ec2Instance.PrivateIpAddress)) - } - if !utils.IsBlank(conv.S(ec2Instance.PublicIpAddress)) { - console.DetailWithResource(" Public IP", conv.S(ec2Instance.PublicIpAddress)) - } - break - } + if elbTargetGroup.LoadBalancerArns != nil { + for _, elbARN := range elbTargetGroup.LoadBalancerArns { + elbLoadBalancer, err := c.awsClient.ELB().RetrieveLoadBalancer(conv.S(elbARN)) + if err != nil { + return console.ExitWithErrorString("Failed to retrieve ELB Load Balancer [%s]: %s", elbARN, err.Error()) + } + + console.DetailWithResource("ELB Load Balancer", conv.S(elbLoadBalancer.LoadBalancerName)) + console.DetailWithResource(" Scheme", conv.S(elbLoadBalancer.Scheme)) + //console.DetailWithResource(" DNS", conv.S(elbLoadBalancer.DNSName)) + if elbLoadBalancer.State != nil { + console.DetailWithResource(" State", fmt.Sprintf("%s %s", + conv.S(elbLoadBalancer.State.Code), + conv.S(elbLoadBalancer.State.Reason))) + } + + // listeners + listeners, err := c.awsClient.ELB().RetrieveLoadBalancerListeners(conv.S(elbARN)) + if err != nil { + return console.ExitWithErrorString("Failed to retrieve Listeners for ELB Load Balancer [%s]: %s", elbARN, err.Error()) + } + for _, listener := range listeners { + if listener.DefaultActions != nil && + len(listener.DefaultActions) > 0 && + conv.S(listener.DefaultActions[0].TargetGroupArn) == conv.S(elbTargetGroup.TargetGroupArn) { + console.DetailWithResource(" Endpoint", fmt.Sprintf("%s://%s:%d", + strings.ToLower(conv.S(listener.Protocol)), + conv.S(elbLoadBalancer.DNSName), + conv.I64(listener.Port))) } - break } } }