-
Notifications
You must be signed in to change notification settings - Fork 302
/
container.go
138 lines (123 loc) · 4.54 KB
/
container.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright 2015-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file is distributed
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing
// permissions and limitations under the License.
package container
import (
"fmt"
"strings"
"github.com/aws/amazon-ecs-cli/ecs-cli/modules/utils/compose"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ecs"
"github.com/docker/libcompose/project"
)
const (
containerNameKey = "Name"
containerStateKey = "State"
containerPortsKey = "Ports"
taskDefinitionKey = "TaskDefinition"
healthKey = "Health"
)
// ContainerInfoColumns is the ordered list of info columns for the ps commands
var ContainerInfoColumns = []string{containerNameKey, containerStateKey, containerPortsKey, taskDefinitionKey, healthKey}
// Container is a wrapper around ecsContainer
type Container struct {
task *ecs.Task
EC2IPAddress string
networkBindings []*ecs.NetworkBinding
ecsContainer *ecs.Container
}
// NewContainer creates a new instance of the container and sets the task id and ecs container to it
func NewContainer(task *ecs.Task, ec2IPAddress string, container *ecs.Container, networkBindings []*ecs.NetworkBinding) Container {
return Container{
task: task,
EC2IPAddress: ec2IPAddress,
networkBindings: networkBindings,
ecsContainer: container,
}
}
// Id returns the ECS container's UUID
func (c *Container) Id() string {
return utils.GetIdFromArn(aws.StringValue(c.ecsContainer.ContainerArn))
}
// Name returns the task's UUID with the container
// ECS doesn't have a describe container API so providing the task's UUID in the name enables users
// to easily look up this container in the ecs world by invoking DescribeTask
func (c *Container) Name() string {
taskID := utils.GetIdFromArn(aws.StringValue(c.task.TaskArn))
return utils.GetFormattedContainerName(taskID, aws.StringValue(c.ecsContainer.Name))
}
// TaskDefinition returns the ECS task definition id which encompasses the container definition, with
// which this container was created
func (c *Container) TaskDefinition() string {
return utils.GetIdFromArn(aws.StringValue(c.task.TaskDefinitionArn))
}
// State returns the status of the container with the exit code and reason of stopped containers if exists
func (c *Container) State() string {
ecsContainer := *c.ecsContainer
status := aws.StringValue(ecsContainer.LastStatus)
if status != ecs.DesiredStatusStopped {
return status
}
// add the exitCode and reason if present for the stopped containers
if ecsContainer.ExitCode != nil {
status = fmt.Sprintf("%s ExitCode: %d", status, aws.Int64Value(ecsContainer.ExitCode))
}
if ecsContainer.Reason != nil {
status = fmt.Sprintf("%s Reason: %s", status, aws.StringValue(ecsContainer.Reason))
}
return status
}
// PortString returns a formatted string with container's network bindings
// in a comma separated fashion
func (c *Container) PortString() string {
result := []string{}
for _, port := range c.networkBindings {
protocol := ecs.TransportProtocolTcp
if port.Protocol != nil {
protocol = aws.StringValue(port.Protocol)
}
ipAddr := aws.StringValue(port.BindIP)
if c.EC2IPAddress != "" {
ipAddr = c.EC2IPAddress
}
portMapping := fmt.Sprintf("%d->%d/%s",
aws.Int64Value(port.HostPort),
aws.Int64Value(port.ContainerPort),
protocol)
portString := portMapping
if ipAddr != "" {
portString = ipAddr + ":" + portMapping
}
result = append(result, portString)
}
return strings.Join(result, ", ")
}
// HealthStatus returns the container healthcheck status for the given container
func (c *Container) HealthStatus() string {
return aws.StringValue(c.ecsContainer.HealthStatus)
}
// ConvertContainersToInfoSet transforms the list of containers into a formatted set of fields
func ConvertContainersToInfoSet(containers []Container) project.InfoSet {
result := project.InfoSet{}
for _, cont := range containers {
info := project.Info{
// TODO: Add more fields
containerNameKey: cont.Name(),
containerStateKey: cont.State(),
containerPortsKey: cont.PortString(),
taskDefinitionKey: cont.TaskDefinition(),
healthKey: cont.HealthStatus(),
}
result = append(result, info)
}
return result
}