forked from remind101/empire
/
client.go
158 lines (127 loc) · 3.87 KB
/
client.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Package ecsutil is a layer on top of Amazon ECS to provide an app aware ECS
// client.
package ecsutil
import (
"strings"
"golang.org/x/net/context"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ecs"
"github.com/remind101/empire/empire/pkg/arn"
)
var (
// DefaultDelimiter is the default delimiter used to separate the app name from
// the service type.
DefaultDelimiter = "--"
)
// Client is an app aware ECS client.
type Client struct {
// client used to interact with the ecs API.
ECS
// The delimiter to use to separate app name from service type. Zero
// value is the DefaultDelimiter.
Delimiter string
}
// NewClient returns a new Client instance using the provided aws.Config.
func NewClient(config *aws.Config) *Client {
return &Client{
ECS: newECSClient(config),
}
}
// CreateAppService creates a new ecs service for the app.
func (c *Client) CreateAppService(ctx context.Context, app string, input *ecs.CreateServiceInput) (*ecs.CreateServiceOutput, error) {
input.ServiceName = c.prefix(app, input.ServiceName)
input.TaskDefinition = c.prefix(app, input.TaskDefinition)
return c.ECS.CreateService(ctx, input)
}
// DeleteAppService deletes the service for the app.
func (c *Client) DeleteAppService(ctx context.Context, app string, input *ecs.DeleteServiceInput) (*ecs.DeleteServiceOutput, error) {
input.Service = c.prefix(app, input.Service)
return c.ECS.DeleteService(ctx, input)
}
// UpdateAppService updates the service for the app.
func (c *Client) UpdateAppService(ctx context.Context, app string, input *ecs.UpdateServiceInput) (*ecs.UpdateServiceOutput, error) {
input.Service = c.prefix(app, input.Service)
input.TaskDefinition = c.prefix(app, input.TaskDefinition)
return c.ECS.UpdateService(ctx, input)
}
// RegisterAppTaskDefinition register a task definition for the app.
func (c *Client) RegisterAppTaskDefinition(ctx context.Context, app string, input *ecs.RegisterTaskDefinitionInput) (*ecs.RegisterTaskDefinitionOutput, error) {
input.Family = c.prefix(app, input.Family)
return c.ECS.RegisterTaskDefinition(ctx, input)
}
// ListAppTasks lists all the tasks for the app.
func (c *Client) ListAppTasks(ctx context.Context, appID string, input *ecs.ListTasksInput) (*ecs.ListTasksOutput, error) {
var arns []*string
resp, err := c.ListAppServices(ctx, appID, &ecs.ListServicesInput{
Cluster: input.Cluster,
})
if err != nil {
return nil, err
}
for _, s := range resp.ServiceARNs {
id, err := arn.ResourceID(*s)
if err != nil {
return nil, err
}
t, err := c.ListTasks(ctx, &ecs.ListTasksInput{
Cluster: input.Cluster,
ServiceName: aws.String(id),
})
if err != nil {
return nil, err
}
if len(t.TaskARNs) == 0 {
continue
}
arns = append(arns, t.TaskARNs...)
}
return &ecs.ListTasksOutput{
TaskARNs: arns,
}, nil
}
// ListAppServices lists all services for the app.
func (c *Client) ListAppServices(ctx context.Context, appID string, input *ecs.ListServicesInput) (*ecs.ListServicesOutput, error) {
resp, err := c.ListServices(ctx, input)
if err != nil {
return resp, err
}
var arns []*string
for _, a := range resp.ServiceARNs {
if a == nil {
continue
}
id, err := arn.ResourceID(*a)
if err != nil {
return resp, err
}
appName, _ := c.split(&id)
if appName == appID {
arns = append(arns, a)
}
}
return &ecs.ListServicesOutput{
ServiceARNs: arns,
}, nil
}
func (c *Client) delimiter() string {
if c.Delimiter == "" {
return DefaultDelimiter
}
return c.Delimiter
}
func (c *Client) prefix(app string, original *string) *string {
if original == nil {
return nil
}
return aws.String(app + c.delimiter() + *original)
}
func (c *Client) split(original *string) (app string, other *string) {
if original == nil {
return "", nil
}
parts := strings.Split(*original, c.delimiter())
if len(parts) < 2 {
return parts[0], nil
}
return parts[0], &parts[1]
}