mirror of https://github.com/docker/compose.git
Merge pull request #795 from docker/kirikou
Store external cluster as metadata
This commit is contained in:
commit
d55f8e4ee1
|
@ -64,10 +64,10 @@ func (r *awsResources) allSecurityGroups() []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse look into compose project for configured resource to use, and check they are valid
|
// parse look into compose project for configured resource to use, and check they are valid
|
||||||
func (b *ecsAPIService) parse(ctx context.Context, project *types.Project) (awsResources, error) {
|
func (b *ecsAPIService) parse(ctx context.Context, project *types.Project, template *cloudformation.Template) (awsResources, error) {
|
||||||
r := awsResources{}
|
r := awsResources{}
|
||||||
var err error
|
var err error
|
||||||
r.cluster, err = b.parseClusterExtension(ctx, project)
|
r.cluster, err = b.parseClusterExtension(ctx, project, template)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return r, err
|
return r, err
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ func (b *ecsAPIService) parse(ctx context.Context, project *types.Project) (awsR
|
||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *ecsAPIService) parseClusterExtension(ctx context.Context, project *types.Project) (string, error) {
|
func (b *ecsAPIService) parseClusterExtension(ctx context.Context, project *types.Project, template *cloudformation.Template) (string, error) {
|
||||||
if x, ok := project.Extensions[extensionCluster]; ok {
|
if x, ok := project.Extensions[extensionCluster]; ok {
|
||||||
cluster := x.(string)
|
cluster := x.(string)
|
||||||
ok, err := b.aws.ClusterExists(ctx, cluster)
|
ok, err := b.aws.ClusterExists(ctx, cluster)
|
||||||
|
@ -100,6 +100,8 @@ func (b *ecsAPIService) parseClusterExtension(ctx context.Context, project *type
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", errors.Wrapf(errdefs.ErrNotFound, "cluster %q does not exist", cluster)
|
return "", errors.Wrapf(errdefs.ErrNotFound, "cluster %q does not exist", cluster)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template.Metadata["Cluster"] = cluster
|
||||||
return cluster, nil
|
return cluster, nil
|
||||||
}
|
}
|
||||||
return "", nil
|
return "", nil
|
||||||
|
|
|
@ -52,12 +52,12 @@ func (b *ecsAPIService) convert(ctx context.Context, project *types.Project) (*c
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resources, err := b.parse(ctx, project)
|
template := cloudformation.NewTemplate()
|
||||||
|
resources, err := b.parse(ctx, project, template)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
template := cloudformation.NewTemplate()
|
|
||||||
err = b.ensureResources(&resources, project, template)
|
err = b.ensureResources(&resources, project, template)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -492,6 +492,18 @@ services:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTemplateMetadata(t *testing.T) {
|
||||||
|
template := convertYaml(t, `
|
||||||
|
x-aws-cluster: "arn:aws:ecs:region:account:cluster/name"
|
||||||
|
services:
|
||||||
|
test:
|
||||||
|
image: nginx
|
||||||
|
`, useDefaultVPC, func(m *MockAPIMockRecorder) {
|
||||||
|
m.ClusterExists(gomock.Any(), "arn:aws:ecs:region:account:cluster/name").Return(true, nil)
|
||||||
|
})
|
||||||
|
assert.Equal(t, template.Metadata["Cluster"], "arn:aws:ecs:region:account:cluster/name")
|
||||||
|
}
|
||||||
|
|
||||||
func convertYaml(t *testing.T, yaml string, fn ...func(m *MockAPIMockRecorder)) *cloudformation.Template {
|
func convertYaml(t *testing.T, yaml string, fn ...func(m *MockAPIMockRecorder)) *cloudformation.Template {
|
||||||
project := loadConfig(t, yaml)
|
project := loadConfig(t, yaml)
|
||||||
ctrl := gomock.NewController(t)
|
ctrl := gomock.NewController(t)
|
||||||
|
|
29
ecs/sdk.go
29
ecs/sdk.go
|
@ -25,6 +25,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/compose-cli/api/compose"
|
"github.com/docker/compose-cli/api/compose"
|
||||||
"github.com/docker/compose-cli/api/secrets"
|
"github.com/docker/compose-cli/api/secrets"
|
||||||
|
"github.com/docker/compose-cli/errdefs"
|
||||||
"github.com/docker/compose-cli/internal"
|
"github.com/docker/compose-cli/internal"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
@ -51,6 +52,7 @@ import (
|
||||||
"github.com/aws/aws-sdk-go/service/ssm"
|
"github.com/aws/aws-sdk-go/service/ssm"
|
||||||
"github.com/aws/aws-sdk-go/service/ssm/ssmiface"
|
"github.com/aws/aws-sdk-go/service/ssm/ssmiface"
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -332,6 +334,7 @@ func (s sdk) ListStacks(ctx context.Context, name string) ([]compose.Stack, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s sdk) GetStackClusterID(ctx context.Context, stack string) (string, error) {
|
func (s sdk) GetStackClusterID(ctx context.Context, stack string) (string, error) {
|
||||||
|
// Note: could use DescribeStackResource but we only can detect `does not exist` case by matching string error message
|
||||||
resources, err := s.CF.ListStackResourcesWithContext(ctx, &cloudformation.ListStackResourcesInput{
|
resources, err := s.CF.ListStackResourcesWithContext(ctx, &cloudformation.ListStackResourcesInput{
|
||||||
StackName: aws.String(stack),
|
StackName: aws.String(stack),
|
||||||
})
|
})
|
||||||
|
@ -343,7 +346,28 @@ func (s sdk) GetStackClusterID(ctx context.Context, stack string) (string, error
|
||||||
return aws.StringValue(r.PhysicalResourceId), nil
|
return aws.StringValue(r.PhysicalResourceId), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "", nil
|
// stack is using user-provided cluster
|
||||||
|
res, err := s.CF.GetTemplateSummaryWithContext(ctx, &cloudformation.GetTemplateSummaryInput{
|
||||||
|
StackName: aws.String(stack),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
c := aws.StringValue(res.Metadata)
|
||||||
|
var m templateMetadata
|
||||||
|
err = json.Unmarshal([]byte(c), &m)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if m.Cluster == "" {
|
||||||
|
return "", errors.Wrap(errdefs.ErrNotFound, "CloudFormation is missing cluster metadata")
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.Cluster, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type templateMetadata struct {
|
||||||
|
Cluster string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s sdk) GetServiceTaskDefinition(ctx context.Context, cluster string, serviceArns []string) (map[string]string, error) {
|
func (s sdk) GetServiceTaskDefinition(ctx context.Context, cluster string, serviceArns []string) (map[string]string, error) {
|
||||||
|
@ -645,6 +669,9 @@ func (s sdk) DescribeService(ctx context.Context, cluster string, arn string) (c
|
||||||
return compose.ServiceStatus{}, err
|
return compose.ServiceStatus{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, f := range services.Failures {
|
||||||
|
return compose.ServiceStatus{}, errors.Wrapf(errdefs.ErrNotFound, "can't get service status %s: %s", aws.StringValue(f.Detail), aws.StringValue(f.Reason))
|
||||||
|
}
|
||||||
service := services.Services[0]
|
service := services.Services[0]
|
||||||
var name string
|
var name string
|
||||||
for _, t := range service.Tags {
|
for _, t := range service.Tags {
|
||||||
|
|
Loading…
Reference in New Issue