浏览代码

Apply linter recommendations

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof 5 年之前
父节点
当前提交
ec4615ae57
共有 25 个文件被更改,包括 213 次插入202 次删除
  1. 0 1
      aci/backend.go
  2. 2 1
      backend/backend.go
  3. 1 1
      cli/cmd/compose/compose.go
  4. 3 3
      client/client.go
  5. 8 6
      compose/api.go
  6. 3 0
      compose/tags.go
  7. 1 1
      ecs/backend.go
  8. 38 41
      ecs/cloudformation.go
  9. 39 34
      ecs/cloudformation_test.go
  10. 21 27
      ecs/colors.go
  11. 5 5
      ecs/compatibility.go
  12. 1 1
      ecs/context.go
  13. 15 14
      ecs/convert.go
  14. 1 1
      ecs/down.go
  15. 8 5
      ecs/iam.go
  16. 2 2
      ecs/list.go
  17. 3 3
      ecs/logs.go
  18. 1 1
      ecs/marshall.go
  19. 26 26
      ecs/sdk.go
  20. 2 0
      ecs/secrets/init.go
  21. 3 3
      ecs/secrets/main/main.go
  22. 10 10
      ecs/up.go
  23. 5 5
      ecs/wait.go
  24. 11 11
      ecs/x.go
  25. 4 0
      secrets/api.go

+ 0 - 1
aci/backend.go

@@ -132,7 +132,6 @@ func (a *aciAPIService) SecretsService() secrets.Service {
 	return nil
 }
 
-
 type aciContainerService struct {
 	ctx store.AciContext
 }

+ 2 - 1
backend/backend.go

@@ -20,12 +20,13 @@ import (
 	"context"
 	"errors"
 	"fmt"
-	"github.com/docker/api/secrets"
+
 	"github.com/sirupsen/logrus"
 
 	"github.com/docker/api/compose"
 	"github.com/docker/api/containers"
 	"github.com/docker/api/context/cloud"
+	"github.com/docker/api/secrets"
 )
 
 var (

+ 1 - 1
cli/cmd/compose/compose.go

@@ -18,8 +18,8 @@ package compose
 
 import (
 	"context"
-	"github.com/compose-spec/compose-go/cli"
 
+	"github.com/compose-spec/compose-go/cli"
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
 

+ 3 - 3
client/client.go

@@ -18,14 +18,14 @@ package client
 
 import (
 	"context"
-	"github.com/docker/api/secrets"
 
-	"github.com/docker/api/context/cloud"
+	"github.com/docker/api/secrets"
 
 	"github.com/docker/api/backend"
 	"github.com/docker/api/compose"
 	"github.com/docker/api/containers"
 	apicontext "github.com/docker/api/context"
+	"github.com/docker/api/context/cloud"
 	"github.com/docker/api/context/store"
 )
 
@@ -71,7 +71,7 @@ func (c *Client) ComposeService() compose.Service {
 	return c.bs.ComposeService()
 }
 
-// ComposeService returns the backend service for the current context
+// SecretsService returns the backend service for the current context
 func (c *Client) SecretsService() secrets.Service {
 	return c.bs.SecretsService()
 }

+ 8 - 6
compose/api.go

@@ -37,6 +37,7 @@ type Service interface {
 	Convert(ctx context.Context, opts *cli.ProjectOptions) ([]byte, error)
 }
 
+// PortPublisher hold status about published port
 type PortPublisher struct {
 	URL           string
 	TargetPort    int
@@ -44,11 +45,12 @@ type PortPublisher struct {
 	Protocol      string
 }
 
+// ServiceStatus hold status about a service
 type ServiceStatus struct {
-	ID            string
-	Name          string
-	Replicas      int
-	Desired       int
-	Ports         []string
-	LoadBalancers []PortPublisher
+	ID         string
+	Name       string
+	Replicas   int
+	Desired    int
+	Ports      []string
+	Publishers []PortPublisher
 }

+ 3 - 0
compose/tags.go

@@ -17,7 +17,10 @@
 package compose
 
 const (
+	// ProjectTag allow to track resource related to a compose project
 	ProjectTag = "com.docker.compose.project"
+	// NetworkTag allow to track resource related to a compose network
 	NetworkTag = "com.docker.compose.network"
+	// ServiceTag allow to track resource related to a compose service
 	ServiceTag = "com.docker.compose.service"
 )

+ 1 - 1
ecs/backend.go

@@ -76,7 +76,7 @@ func getEcsAPIService(ecsCtx store.EcsContext) (*ecsAPIService, error) {
 	return &ecsAPIService{
 		ctx:    ecsCtx,
 		Region: ecsCtx.Region,
-		SDK:    NewSDK(sess),
+		SDK:    newSDK(sess),
 	}, nil
 }
 

+ 38 - 41
ecs/cloudformation.go

@@ -46,11 +46,11 @@ import (
 )
 
 const (
-	ParameterClusterName     = "ParameterClusterName"
-	ParameterVPCId           = "ParameterVPCId"
-	ParameterSubnet1Id       = "ParameterSubnet1Id"
-	ParameterSubnet2Id       = "ParameterSubnet2Id"
-	ParameterLoadBalancerARN = "ParameterLoadBalancerARN"
+	parameterClusterName     = "ParameterClusterName"
+	parameterVPCId           = "ParameterVPCId"
+	parameterSubnet1Id       = "ParameterSubnet1Id"
+	parameterSubnet2Id       = "ParameterSubnet2Id"
+	parameterLoadBalancerARN = "ParameterLoadBalancerARN"
 )
 
 func (b *ecsAPIService) Convert(ctx context.Context, opts *cli.ProjectOptions) ([]byte, error) {
@@ -62,12 +62,12 @@ func (b *ecsAPIService) Convert(ctx context.Context, opts *cli.ProjectOptions) (
 	if err != nil {
 		return nil, err
 	}
-	return Marshall(template)
+	return marshall(template)
 }
 
 // Convert a compose project into a CloudFormation template
-func (b *ecsAPIService) convert(project *types.Project) (*cloudformation.Template, error) {
-	var checker compatibility.Checker = &FargateCompatibilityChecker{
+func (b *ecsAPIService) convert(project *types.Project) (*cloudformation.Template, error) { //nolint:gocyclo
+	var checker compatibility.Checker = &fargateCompatibilityChecker{
 		compatibility.AllowList{
 			Supported: compatibleComposeAttributes,
 		},
@@ -86,12 +86,12 @@ func (b *ecsAPIService) convert(project *types.Project) (*cloudformation.Templat
 
 	template := cloudformation.NewTemplate()
 	template.Description = "CloudFormation template created by Docker for deploying applications on Amazon ECS"
-	template.Parameters[ParameterClusterName] = cloudformation.Parameter{
+	template.Parameters[parameterClusterName] = cloudformation.Parameter{
 		Type:        "String",
 		Description: "Name of the ECS cluster to deploy to (optional)",
 	}
 
-	template.Parameters[ParameterVPCId] = cloudformation.Parameter{
+	template.Parameters[parameterVPCId] = cloudformation.Parameter{
 		Type:        "AWS::EC2::VPC::Id",
 		Description: "ID of the VPC",
 	}
@@ -103,28 +103,28 @@ func (b *ecsAPIService) convert(project *types.Project) (*cloudformation.Templat
 			Description: "The list of SubnetIds, for at least two Availability Zones in the region in your VPC",
 		}
 	*/
-	template.Parameters[ParameterSubnet1Id] = cloudformation.Parameter{
+	template.Parameters[parameterSubnet1Id] = cloudformation.Parameter{
 		Type:        "AWS::EC2::Subnet::Id",
 		Description: "SubnetId, for Availability Zone 1 in the region in your VPC",
 	}
-	template.Parameters[ParameterSubnet2Id] = cloudformation.Parameter{
+	template.Parameters[parameterSubnet2Id] = cloudformation.Parameter{
 		Type:        "AWS::EC2::Subnet::Id",
 		Description: "SubnetId, for Availability Zone 2 in the region in your VPC",
 	}
 
-	template.Parameters[ParameterLoadBalancerARN] = cloudformation.Parameter{
+	template.Parameters[parameterLoadBalancerARN] = cloudformation.Parameter{
 		Type:        "String",
 		Description: "Name of the LoadBalancer to connect to (optional)",
 	}
 
 	// Create Cluster is `ParameterClusterName` parameter is not set
-	template.Conditions["CreateCluster"] = cloudformation.Equals("", cloudformation.Ref(ParameterClusterName))
+	template.Conditions["CreateCluster"] = cloudformation.Equals("", cloudformation.Ref(parameterClusterName))
 
 	cluster := createCluster(project, template)
 
 	networks := map[string]string{}
 	for _, net := range project.Networks {
-		networks[net.Name] = convertNetwork(project, net, cloudformation.Ref(ParameterVPCId), template)
+		networks[net.Name] = convertNetwork(project, net, cloudformation.Ref(parameterVPCId), template)
 	}
 
 	for i, s := range project.Secrets {
@@ -175,9 +175,6 @@ func (b *ecsAPIService) convert(project *types.Project) (*cloudformation.Templat
 		template.Resources[taskDefinition] = definition
 
 		var healthCheck *cloudmap.Service_HealthCheckConfig
-		if service.HealthCheck != nil && !service.HealthCheck.Disable {
-			// FIXME ECS only support HTTP(s) health checks, while Docker only support CMD
-		}
 
 		serviceRegistry := createServiceRegistry(service, template, healthCheck)
 
@@ -242,8 +239,8 @@ func (b *ecsAPIService) convert(project *types.Project) (*cloudformation.Templat
 					AssignPublicIp: ecsapi.AssignPublicIpEnabled,
 					SecurityGroups: serviceSecurityGroups,
 					Subnets: []string{
-						cloudformation.Ref(ParameterSubnet1Id),
-						cloudformation.Ref(ParameterSubnet2Id),
+						cloudformation.Ref(parameterSubnet1Id),
+						cloudformation.Ref(parameterSubnet2Id),
 					},
 				},
 			},
@@ -268,7 +265,7 @@ func (b *ecsAPIService) convert(project *types.Project) (*cloudformation.Templat
 
 func createLogGroup(project *types.Project, template *cloudformation.Template) {
 	retention := 0
-	if v, ok := project.Extensions[ExtensionRetention]; ok {
+	if v, ok := project.Extensions[extensionRetention]; ok {
 		retention = v.(int)
 	}
 	logGroup := fmt.Sprintf("/docker-compose/%s", project.Name)
@@ -285,11 +282,11 @@ func computeRollingUpdateLimits(service types.ServiceConfig) (int, int, error) {
 		return minPercent, maxPercent, nil
 	}
 	updateConfig := service.Deploy.UpdateConfig
-	min, okMin := updateConfig.Extensions[ExtensionMinPercent]
+	min, okMin := updateConfig.Extensions[extensionMinPercent]
 	if okMin {
 		minPercent = min.(int)
 	}
-	max, okMax := updateConfig.Extensions[ExtensionMaxPercent]
+	max, okMax := updateConfig.Extensions[extensionMaxPercent]
 	if okMax {
 		maxPercent = max.(int)
 	}
@@ -333,7 +330,7 @@ func getLoadBalancerSecurityGroups(project *types.Project, template *cloudformat
 	securityGroups := []string{}
 	for _, network := range project.Networks {
 		if !network.Internal {
-			net := convertNetwork(project, network, cloudformation.Ref(ParameterVPCId), template)
+			net := convertNetwork(project, network, cloudformation.Ref(parameterVPCId), template)
 			securityGroups = append(securityGroups, net)
 		}
 	}
@@ -354,7 +351,7 @@ func createLoadBalancer(project *types.Project, template *cloudformation.Templat
 	// load balancer names are limited to 32 characters total
 	loadBalancerName := fmt.Sprintf("%.32s", fmt.Sprintf("%sLoadBalancer", strings.Title(project.Name)))
 	// Create PortPublisher if `ParameterLoadBalancerName` is not set
-	template.Conditions["CreateLoadBalancer"] = cloudformation.Equals("", cloudformation.Ref(ParameterLoadBalancerARN))
+	template.Conditions["CreateLoadBalancer"] = cloudformation.Equals("", cloudformation.Ref(parameterLoadBalancerARN))
 
 	loadBalancerType := getLoadBalancerType(project)
 	securityGroups := []string{}
@@ -367,8 +364,8 @@ func createLoadBalancer(project *types.Project, template *cloudformation.Templat
 		Scheme:         elbv2.LoadBalancerSchemeEnumInternetFacing,
 		SecurityGroups: securityGroups,
 		Subnets: []string{
-			cloudformation.Ref(ParameterSubnet1Id),
-			cloudformation.Ref(ParameterSubnet2Id),
+			cloudformation.Ref(parameterSubnet1Id),
+			cloudformation.Ref(parameterSubnet2Id),
 		},
 		Tags: []tags.Tag{
 			{
@@ -379,7 +376,7 @@ func createLoadBalancer(project *types.Project, template *cloudformation.Templat
 		Type:                       loadBalancerType,
 		AWSCloudFormationCondition: "CreateLoadBalancer",
 	}
-	return cloudformation.If("CreateLoadBalancer", cloudformation.Ref(loadBalancerName), cloudformation.Ref(ParameterLoadBalancerARN))
+	return cloudformation.If("CreateLoadBalancer", cloudformation.Ref(loadBalancerName), cloudformation.Ref(parameterLoadBalancerARN))
 }
 
 func createListener(service types.ServiceConfig, port types.ServicePortConfig, template *cloudformation.Template, targetGroupName string, loadBalancerARN string, protocol string) string {
@@ -427,7 +424,7 @@ func createTargetGroup(project *types.Project, service types.ServiceConfig, port
 				Value: project.Name,
 			},
 		},
-		VpcId:      cloudformation.Ref(ParameterVPCId),
+		VpcId:      cloudformation.Ref(parameterVPCId),
 		TargetType: elbv2.TargetTypeEnumIp,
 	}
 	return targetGroupName
@@ -462,7 +459,7 @@ func createServiceRegistry(service types.ServiceConfig, template *cloudformation
 
 func createTaskExecutionRole(service types.ServiceConfig, err error, definition *ecs.TaskDefinition, template *cloudformation.Template) (string, error) {
 	taskExecutionRole := fmt.Sprintf("%sTaskExecutionRole", normalizeResourceName(service.Name))
-	policy, err := getPolicy(definition)
+	policy := getPolicy(definition)
 	if err != nil {
 		return taskExecutionRole, err
 	}
@@ -474,16 +471,16 @@ func createTaskExecutionRole(service types.ServiceConfig, err error, definition
 		})
 	}
 
-	if roles, ok := service.Extensions[ExtensionRole]; ok {
+	if roles, ok := service.Extensions[extensionRole]; ok {
 		rolePolicies = append(rolePolicies, iam.Role_Policy{
 			PolicyDocument: roles,
 		})
 	}
 	managedPolicies := []string{
-		ECSTaskExecutionPolicy,
-		ECRReadOnlyPolicy,
+		ecsTaskExecutionPolicy,
+		ecrReadOnlyPolicy,
 	}
-	if v, ok := service.Extensions[ExtensionManagedPolicies]; ok {
+	if v, ok := service.Extensions[extensionManagedPolicies]; ok {
 		for _, s := range v.([]interface{}) {
 			managedPolicies = append(managedPolicies, s.(string))
 		}
@@ -507,7 +504,7 @@ func createCluster(project *types.Project, template *cloudformation.Template) st
 		},
 		AWSCloudFormationCondition: "CreateCluster",
 	}
-	cluster := cloudformation.If("CreateCluster", cloudformation.Ref("Cluster"), cloudformation.Ref(ParameterClusterName))
+	cluster := cloudformation.If("CreateCluster", cloudformation.Ref("Cluster"), cloudformation.Ref(parameterClusterName))
 	return cluster
 }
 
@@ -515,12 +512,12 @@ func createCloudMap(project *types.Project, template *cloudformation.Template) {
 	template.Resources["CloudMap"] = &cloudmap.PrivateDnsNamespace{
 		Description: fmt.Sprintf("Service Map for Docker Compose project %s", project.Name),
 		Name:        fmt.Sprintf("%s.local", project.Name),
-		Vpc:         cloudformation.Ref(ParameterVPCId),
+		Vpc:         cloudformation.Ref(parameterVPCId),
 	}
 }
 
 func convertNetwork(project *types.Project, net types.NetworkConfig, vpc string, template *cloudformation.Template) string {
-	if sg, ok := net.Extensions[ExtensionSecurityGroup]; ok {
+	if sg, ok := net.Extensions[extensionSecurityGroup]; ok {
 		logrus.Debugf("Security Group for network %q set by user to %q", net.Name, sg)
 		return sg.(string)
 	}
@@ -583,7 +580,7 @@ func normalizeResourceName(s string) string {
 	return strings.Title(regexp.MustCompile("[^a-zA-Z0-9]+").ReplaceAllString(s, ""))
 }
 
-func getPolicy(taskDef *ecs.TaskDefinition) (*PolicyDocument, error) {
+func getPolicy(taskDef *ecs.TaskDefinition) *PolicyDocument {
 	arns := []string{}
 	for _, container := range taskDef.ContainerDefinitions {
 		if container.RepositoryCredentials != nil {
@@ -601,12 +598,12 @@ func getPolicy(taskDef *ecs.TaskDefinition) (*PolicyDocument, error) {
 			Statement: []PolicyStatement{
 				{
 					Effect:   "Allow",
-					Action:   []string{ActionGetSecretValue, ActionGetParameters, ActionDecrypt},
+					Action:   []string{actionGetSecretValue, actionGetParameters, actionDecrypt},
 					Resource: arns,
 				}},
-		}, nil
+		}
 	}
-	return nil, nil
+	return nil
 }
 
 func uniqueStrings(items []string) []string {

+ 39 - 34
ecs/cloudformation_test.go

@@ -45,7 +45,7 @@ func TestSimpleConvert(t *testing.T) {
 }
 
 func TestLogging(t *testing.T) {
-	template := convertYaml(t, "test", `
+	template := convertYaml(t, `
 services:
   foo:
     image: hello_world
@@ -64,7 +64,7 @@ x-aws-logs_retention: 10
 }
 
 func TestEnvFile(t *testing.T) {
-	template := convertYaml(t, "test", `
+	template := convertYaml(t, `
 services:
   foo:
     image: hello_world
@@ -84,7 +84,7 @@ services:
 }
 
 func TestEnvFileAndEnv(t *testing.T) {
-	template := convertYaml(t, "test", `
+	template := convertYaml(t, `
 services:
   foo:
     image: hello_world
@@ -106,7 +106,7 @@ services:
 }
 
 func TestRollingUpdateLimits(t *testing.T) {
-	template := convertYaml(t, "test", `
+	template := convertYaml(t, `
 services:
   foo:
     image: hello_world
@@ -121,7 +121,7 @@ services:
 }
 
 func TestRollingUpdateExtension(t *testing.T) {
-	template := convertYaml(t, "test", `
+	template := convertYaml(t, `
 services:
   foo:
     image: hello_world
@@ -136,16 +136,17 @@ services:
 }
 
 func TestRolePolicy(t *testing.T) {
-	template := convertYaml(t, "test", `
+	template := convertYaml(t, `
 services:
   foo:
     image: hello_world
     x-aws-pull_credentials: "secret"
 `)
-	role := template.Resources["FooTaskExecutionRole"].(*iam.Role)
-	assert.Check(t, role != nil)
-	assert.Check(t, role.ManagedPolicyArns[0] == ECSTaskExecutionPolicy)
-	assert.Check(t, role.ManagedPolicyArns[1] == ECRReadOnlyPolicy)
+	x := template.Resources["FooTaskExecutionRole"]
+	assert.Check(t, x != nil)
+	role := *(x.(*iam.Role))
+	assert.Check(t, role.ManagedPolicyArns[0] == ecsTaskExecutionPolicy)
+	assert.Check(t, role.ManagedPolicyArns[1] == ecrReadOnlyPolicy)
 	// We expect an extra policy has been created for x-aws-pull_credentials
 	assert.Check(t, len(role.Policies) == 1)
 	policy := role.Policies[0].PolicyDocument.(*PolicyDocument)
@@ -155,7 +156,7 @@ services:
 }
 
 func TestMapNetworksToSecurityGroups(t *testing.T) {
-	template := convertYaml(t, "test", `
+	template := convertYaml(t, `
 services:
   test:
     image: hello_world
@@ -172,29 +173,31 @@ networks:
 	assert.Check(t, template.Resources["TestPublicNetwork"] != nil)
 	assert.Check(t, template.Resources["TestBacktierNetwork"] != nil)
 	assert.Check(t, template.Resources["TestBacktierNetworkIngress"] != nil)
-	ingress := template.Resources["TestPublicNetworkIngress"].(*ec2.SecurityGroupIngress)
-	assert.Check(t, ingress != nil)
+	i := template.Resources["TestPublicNetworkIngress"]
+	assert.Check(t, i != nil)
+	ingress := *i.(*ec2.SecurityGroupIngress)
 	assert.Check(t, ingress.SourceSecurityGroupId == cloudformation.Ref("TestPublicNetwork"))
 
 }
 
 func TestLoadBalancerTypeApplication(t *testing.T) {
-	template := convertYaml(t, "test123456789009876543211234567890", `
+	template := convertYaml(t, `
 services:
   test:
     image: nginx
     ports:
       - 80:80
 `)
-	lb := template.Resources["TestLoadBalancer"].(*elasticloadbalancingv2.LoadBalancer)
+	lb := template.Resources["TestLoadBalancer"]
 	assert.Check(t, lb != nil)
-	assert.Check(t, len(lb.Name) <= 32)
-	assert.Check(t, lb.Type == elbv2.LoadBalancerTypeEnumApplication)
-	assert.Check(t, len(lb.SecurityGroups) > 0)
+	loadBalancer := *lb.(*elasticloadbalancingv2.LoadBalancer)
+	assert.Check(t, len(loadBalancer.Name) <= 32)
+	assert.Check(t, loadBalancer.Type == elbv2.LoadBalancerTypeEnumApplication)
+	assert.Check(t, len(loadBalancer.SecurityGroups) > 0)
 }
 
 func TestNoLoadBalancerIfNoPortExposed(t *testing.T) {
-	template := convertYaml(t, "test", `
+	template := convertYaml(t, `
 services:
   test:
     image: nginx
@@ -209,20 +212,21 @@ services:
 }
 
 func TestServiceReplicas(t *testing.T) {
-	template := convertYaml(t, "test", `
+	template := convertYaml(t, `
 services:
   test:
     image: nginx
     deploy:
       replicas: 10
 `)
-	s := template.Resources["TestService"].(*ecs.Service)
+	s := template.Resources["TestService"]
 	assert.Check(t, s != nil)
-	assert.Check(t, s.DesiredCount == 10)
+	service := *s.(*ecs.Service)
+	assert.Check(t, service.DesiredCount == 10)
 }
 
 func TestTaskSizeConvert(t *testing.T) {
-	template := convertYaml(t, "test", `
+	template := convertYaml(t, `
 services:
   test:
     image: nginx
@@ -239,7 +243,7 @@ services:
 	assert.Equal(t, def.Cpu, "512")
 	assert.Equal(t, def.Memory, "2048")
 
-	template = convertYaml(t, "test", `
+	template = convertYaml(t, `
 services:
   test:
     image: nginx
@@ -257,7 +261,7 @@ services:
 	assert.Equal(t, def.Memory, "8192")
 }
 func TestTaskSizeConvertFailure(t *testing.T) {
-	model := loadConfig(t, "test", `
+	model := loadConfig(t, `
 services:
   test:
     image: nginx
@@ -273,7 +277,7 @@ services:
 }
 
 func TestLoadBalancerTypeNetwork(t *testing.T) {
-	template := convertYaml(t, "test", `
+	template := convertYaml(t, `
 services:
   test:
     image: nginx
@@ -281,13 +285,14 @@ services:
       - 80:80
       - 88:88
 `)
-	lb := template.Resources["TestLoadBalancer"].(*elasticloadbalancingv2.LoadBalancer)
+	lb := template.Resources["TestLoadBalancer"]
 	assert.Check(t, lb != nil)
-	assert.Check(t, lb.Type == elbv2.LoadBalancerTypeEnumNetwork)
+	loadBalancer := *lb.(*elasticloadbalancingv2.LoadBalancer)
+	assert.Check(t, loadBalancer.Type == elbv2.LoadBalancerTypeEnumNetwork)
 }
 
 func TestServiceMapping(t *testing.T) {
-	template := convertYaml(t, "test", `
+	template := convertYaml(t, `
 services:
   test:
     image: "image"
@@ -326,7 +331,7 @@ func get(l []ecs.TaskDefinition_KeyValuePair, name string) string {
 }
 
 func TestResourcesHaveProjectTagSet(t *testing.T) {
-	template := convertYaml(t, "test", `
+	template := convertYaml(t, `
 services:
   test:
     image: nginx
@@ -353,7 +358,7 @@ func convertResultAsString(t *testing.T, project *types.Project) string {
 	backend := &ecsAPIService{}
 	template, err := backend.convert(project)
 	assert.NilError(t, err)
-	resultAsJSON, err := Marshall(template)
+	resultAsJSON, err := marshall(template)
 	assert.NilError(t, err)
 	return fmt.Sprintf("%s\n", string(resultAsJSON))
 }
@@ -368,15 +373,15 @@ func load(t *testing.T, paths ...string) *types.Project {
 	return project
 }
 
-func convertYaml(t *testing.T, name string, yaml string) *cloudformation.Template {
-	project := loadConfig(t, name, yaml)
+func convertYaml(t *testing.T, yaml string) *cloudformation.Template {
+	project := loadConfig(t, yaml)
 	backend := &ecsAPIService{}
 	template, err := backend.convert(project)
 	assert.NilError(t, err)
 	return template
 }
 
-func loadConfig(t *testing.T, name string, yaml string) *types.Project {
+func loadConfig(t *testing.T, yaml string) *types.Project {
 	dict, err := loader.ParseYAML([]byte(yaml))
 	assert.NilError(t, err)
 	model, err := loader.Load(types.ConfigDetails{

+ 21 - 27
ecs/colors.go

@@ -21,7 +21,7 @@ import (
 	"strconv"
 )
 
-var NAMES = []string{
+var names = []string{
 	"grey",
 	"red",
 	"green",
@@ -32,14 +32,8 @@ var NAMES = []string{
 	"white",
 }
 
-var COLORS map[string]ColorFunc
-
-// ColorFunc use ANSI codes to render colored text on console
-type ColorFunc func(s string) string
-
-var Monochrome = func(s string) string {
-	return s
-}
+// colorFunc use ANSI codes to render colored text on console
+type colorFunc func(s string) string
 
 func ansiColor(code, s string) string {
 	return fmt.Sprintf("%s%s%s", ansi(code), s, ansi("0"))
@@ -49,38 +43,38 @@ func ansi(code string) string {
 	return fmt.Sprintf("\033[%sm", code)
 }
 
-func makeColorFunc(code string) ColorFunc {
+func makeColorFunc(code string) colorFunc {
 	return func(s string) string {
 		return ansiColor(code, s)
 	}
 }
 
-var Rainbow = make(chan ColorFunc)
+var loop = make(chan colorFunc)
 
 func init() {
-	COLORS = map[string]ColorFunc{}
-	for i, name := range NAMES {
-		COLORS[name] = makeColorFunc(strconv.Itoa(30 + i))
-		COLORS["intense_"+name] = makeColorFunc(strconv.Itoa(30+i) + ";1")
+	colors := map[string]colorFunc{}
+	for i, name := range names {
+		colors[name] = makeColorFunc(strconv.Itoa(30 + i))
+		colors["intense_"+name] = makeColorFunc(strconv.Itoa(30+i) + ";1")
 	}
 
 	go func() {
 		i := 0
-		rainbow := []ColorFunc{
-			COLORS["cyan"],
-			COLORS["yellow"],
-			COLORS["green"],
-			COLORS["magenta"],
-			COLORS["blue"],
-			COLORS["intense_cyan"],
-			COLORS["intense_yellow"],
-			COLORS["intense_green"],
-			COLORS["intense_magenta"],
-			COLORS["intense_blue"],
+		rainbow := []colorFunc{
+			colors["cyan"],
+			colors["yellow"],
+			colors["green"],
+			colors["magenta"],
+			colors["blue"],
+			colors["intense_cyan"],
+			colors["intense_yellow"],
+			colors["intense_green"],
+			colors["intense_magenta"],
+			colors["intense_blue"],
 		}
 
 		for {
-			Rainbow <- rainbow[i]
+			loop <- rainbow[i]
 			i = (i + 1) % len(rainbow)
 		}
 	}()

+ 5 - 5
ecs/compatibility.go

@@ -21,7 +21,7 @@ import (
 	"github.com/compose-spec/compose-go/types"
 )
 
-type FargateCompatibilityChecker struct {
+type fargateCompatibilityChecker struct {
 	compatibility.AllowList
 }
 
@@ -68,13 +68,13 @@ var compatibleComposeAttributes = []string{
 	"secrets.file",
 }
 
-func (c *FargateCompatibilityChecker) CheckImage(service *types.ServiceConfig) {
+func (c *fargateCompatibilityChecker) CheckImage(service *types.ServiceConfig) {
 	if service.Image == "" {
 		c.Incompatible("service %s doesn't define a Docker image to run", service.Name)
 	}
 }
 
-func (c *FargateCompatibilityChecker) CheckPortsPublished(p *types.ServicePortConfig) {
+func (c *fargateCompatibilityChecker) CheckPortsPublished(p *types.ServicePortConfig) {
 	if p.Published == 0 {
 		p.Published = p.Target
 	}
@@ -83,7 +83,7 @@ func (c *FargateCompatibilityChecker) CheckPortsPublished(p *types.ServicePortCo
 	}
 }
 
-func (c *FargateCompatibilityChecker) CheckCapAdd(service *types.ServiceConfig) {
+func (c *fargateCompatibilityChecker) CheckCapAdd(service *types.ServiceConfig) {
 	add := []string{}
 	for _, cap := range service.CapAdd {
 		switch cap {
@@ -96,7 +96,7 @@ func (c *FargateCompatibilityChecker) CheckCapAdd(service *types.ServiceConfig)
 	service.CapAdd = add
 }
 
-func (c *FargateCompatibilityChecker) CheckLoggingDriver(config *types.LoggingConfig) {
+func (c *fargateCompatibilityChecker) CheckLoggingDriver(config *types.LoggingConfig) {
 	if config.Driver != "" && config.Driver != "awslogs" {
 		c.Unsupported("services.logging.driver %s is not supported", config.Driver)
 	}

+ 1 - 1
ecs/context.go

@@ -103,7 +103,7 @@ func (h contextCreateAWSHelper) saveCredentials(profile string, accessKeyID stri
 	p := credentials.SharedCredentialsProvider{Profile: profile}
 	_, err := p.Retrieve()
 	if err == nil {
-		return fmt.Errorf("credentials already exists!")
+		return fmt.Errorf("credentials already exists")
 	}
 
 	if err.(awserr.Error).Code() == "SharedCredsLoad" && err.(awserr.Error).Message() == "failed to load shared credentials file" {

+ 15 - 14
ecs/convert.go

@@ -44,10 +44,7 @@ func convert(project *types.Project, service types.ServiceConfig) (*ecs.TaskDefi
 	if err != nil {
 		return nil, err
 	}
-	_, memReservation, err := toContainerReservation(service)
-	if err != nil {
-		return nil, err
-	}
+	_, memReservation := toContainerReservation(service)
 	credential := getRepoCredentials(service)
 
 	// override resolve.conf search directive to also search <project>.local
@@ -141,7 +138,11 @@ func convert(project *types.Project, service types.ServiceConfig) (*ecs.TaskDefi
 	}, nil
 }
 
-func createSecretsSideCar(project *types.Project, service types.ServiceConfig, logConfiguration *ecs.TaskDefinition_LogConfiguration) (ecs.TaskDefinition_Volume, ecs.TaskDefinition_MountPoint, ecs.TaskDefinition_ContainerDefinition, error) {
+func createSecretsSideCar(project *types.Project, service types.ServiceConfig, logConfiguration *ecs.TaskDefinition_LogConfiguration) (
+	ecs.TaskDefinition_Volume,
+	ecs.TaskDefinition_MountPoint,
+	ecs.TaskDefinition_ContainerDefinition,
+	error) {
 	initContainerName := fmt.Sprintf("%s_Secrets_InitContainer", normalizeResourceName(service.Name))
 	secretsVolume := ecs.TaskDefinition_Volume{
 		Name: "secrets",
@@ -166,7 +167,7 @@ func createSecretsSideCar(project *types.Project, service types.ServiceConfig, l
 			ValueFrom: secretConfig.Name,
 		})
 		var keys []string
-		if ext, ok := secretConfig.Extensions[ExtensionKeys]; ok {
+		if ext, ok := secretConfig.Extensions[extensionKeys]; ok {
 			if key, ok := ext.(string); ok {
 				keys = append(keys, key)
 			} else {
@@ -275,7 +276,7 @@ func toSystemControls(sysctls types.Mapping) []ecs.TaskDefinition_SystemControl
 	return sys
 }
 
-const MiB = 1024 * 1024
+const miB = 1024 * 1024
 
 func toLimits(service types.ServiceConfig) (string, string, error) {
 	// All possible cpu/mem values for Fargate
@@ -315,9 +316,9 @@ func toLimits(service types.ServiceConfig) (string, string, error) {
 
 	for _, cpu := range cpus {
 		mem := cpuToMem[cpu]
-		if v <= cpu*MiB {
+		if v <= cpu*miB {
 			for _, m := range mem {
-				if limits.MemoryBytes <= m*MiB {
+				if limits.MemoryBytes <= m*miB {
 					cpuLimit = strconv.FormatInt(cpu, 10)
 					memLimit = strconv.FormatInt(int64(m), 10)
 					return cpuLimit, memLimit, nil
@@ -328,19 +329,19 @@ func toLimits(service types.ServiceConfig) (string, string, error) {
 	return "", "", fmt.Errorf("the resources requested are not supported by ECS/Fargate")
 }
 
-func toContainerReservation(service types.ServiceConfig) (string, int, error) {
+func toContainerReservation(service types.ServiceConfig) (string, int) {
 	cpuReservation := ".0"
 	memReservation := 0
 
 	if service.Deploy == nil {
-		return cpuReservation, memReservation, nil
+		return cpuReservation, memReservation
 	}
 
 	reservations := service.Deploy.Resources.Reservations
 	if reservations == nil {
-		return cpuReservation, memReservation, nil
+		return cpuReservation, memReservation
 	}
-	return reservations.NanoCPUs, int(reservations.MemoryBytes / MiB), nil
+	return reservations.NanoCPUs, int(reservations.MemoryBytes / miB)
 }
 
 func toPlacementConstraints(deploy *types.DeployConfig) []ecs.TaskDefinition_TaskDefinitionPlacementConstraint {
@@ -467,7 +468,7 @@ func toHostEntryPtr(hosts types.HostsList) []ecs.TaskDefinition_HostEntry {
 func getRepoCredentials(service types.ServiceConfig) *ecs.TaskDefinition_RepositoryCredentials {
 	// extract registry and namespace string from image name
 	for key, value := range service.Extensions {
-		if key == ExtensionPullCredentials {
+		if key == extensionPullCredentials {
 			return &ecs.TaskDefinition_RepositoryCredentials{CredentialsParameter: value.(string)}
 		}
 	}

+ 1 - 1
ecs/down.go

@@ -32,7 +32,7 @@ func (b *ecsAPIService) Down(ctx context.Context, options *cli.ProjectOptions) e
 	if err != nil {
 		return err
 	}
-	return b.WaitStackCompletion(ctx, name, StackDelete)
+	return b.WaitStackCompletion(ctx, name, stackDelete)
 }
 
 func (b *ecsAPIService) projectName(options *cli.ProjectOptions) (string, error) {

+ 8 - 5
ecs/iam.go

@@ -17,12 +17,12 @@
 package ecs
 
 const (
-	ECSTaskExecutionPolicy = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
-	ECRReadOnlyPolicy      = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
+	ecsTaskExecutionPolicy = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
+	ecrReadOnlyPolicy      = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
 
-	ActionGetSecretValue = "secretsmanager:GetSecretValue"
-	ActionGetParameters  = "ssm:GetParameters"
-	ActionDecrypt        = "kms:Decrypt"
+	actionGetSecretValue = "secretsmanager:GetSecretValue"
+	actionGetParameters  = "ssm:GetParameters"
+	actionDecrypt        = "kms:Decrypt"
 )
 
 var assumeRolePolicyDocument = PolicyDocument{
@@ -38,12 +38,14 @@ var assumeRolePolicyDocument = PolicyDocument{
 	},
 }
 
+// PolicyDocument describes an IAM policy document
 // could alternatively depend on https://github.com/kubernetes-sigs/cluster-api-provider-aws/blob/master/cmd/clusterawsadm/api/iam/v1alpha1/types.go
 type PolicyDocument struct {
 	Version   string            `json:",omitempty"`
 	Statement []PolicyStatement `json:",omitempty"`
 }
 
+// PolicyStatement describes an IAM policy statement
 type PolicyStatement struct {
 	Effect    string          `json:",omitempty"`
 	Action    []string        `json:",omitempty"`
@@ -51,6 +53,7 @@ type PolicyStatement struct {
 	Resource  []string        `json:",omitempty"`
 }
 
+// PolicyPrincipal describes an IAM policy principal
 type PolicyPrincipal struct {
 	Service string `json:",omitempty"`
 }

+ 2 - 2
ecs/list.go

@@ -35,7 +35,7 @@ func (b *ecsAPIService) Ps(ctx context.Context, options *cli.ProjectOptions) ([]
 	if err != nil {
 		return nil, err
 	}
-	cluster := parameters[ParameterClusterName]
+	cluster := parameters[parameterClusterName]
 
 	resources, err := b.SDK.ListStackResources(ctx, projectName)
 	if err != nil {
@@ -61,7 +61,7 @@ func (b *ecsAPIService) Ps(ctx context.Context, options *cli.ProjectOptions) ([]
 
 	for i, state := range status {
 		ports := []string{}
-		for _, lb := range state.LoadBalancers {
+		for _, lb := range state.Publishers {
 			ports = append(ports, fmt.Sprintf(
 				"%s:%d->%d/%s",
 				lb.URL,

+ 3 - 3
ecs/logs.go

@@ -40,7 +40,7 @@ func (b *ecsAPIService) Logs(ctx context.Context, options *cli.ProjectOptions, w
 	}
 
 	consumer := logConsumer{
-		colors: map[string]ColorFunc{},
+		colors: map[string]colorFunc{},
 		width:  0,
 		writer: writer,
 	}
@@ -58,7 +58,7 @@ func (b *ecsAPIService) Logs(ctx context.Context, options *cli.ProjectOptions, w
 func (l *logConsumer) Log(service, container, message string) {
 	cf, ok := l.colors[service]
 	if !ok {
-		cf = <-Rainbow
+		cf = <-loop
 		l.colors[service] = cf
 		l.computeWidth()
 	}
@@ -81,7 +81,7 @@ func (l *logConsumer) computeWidth() {
 }
 
 type logConsumer struct {
-	colors map[string]ColorFunc
+	colors map[string]colorFunc
 	width  int
 	writer io.Writer
 }

+ 1 - 1
ecs/marshall.go

@@ -24,7 +24,7 @@ import (
 	"github.com/awslabs/goformation/v4/cloudformation"
 )
 
-func Marshall(template *cloudformation.Template) ([]byte, error) {
+func marshall(template *cloudformation.Template) ([]byte, error) {
 	raw, err := template.JSON()
 	if err != nil {
 		return nil, err

+ 26 - 26
ecs/sdk.go

@@ -22,11 +22,12 @@ import (
 	"strings"
 	"time"
 
+	"github.com/aws/aws-sdk-go/aws/client"
+
 	"github.com/docker/api/compose"
 	"github.com/docker/api/secrets"
 
 	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/session"
 	"github.com/aws/aws-sdk-go/service/cloudformation"
 	"github.com/aws/aws-sdk-go/service/cloudformation/cloudformationiface"
 	"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
@@ -46,17 +47,16 @@ import (
 )
 
 type sdk struct {
-	sess *session.Session
-	ECS  ecsiface.ECSAPI
-	EC2  ec2iface.EC2API
-	ELB  elbv2iface.ELBV2API
-	CW   cloudwatchlogsiface.CloudWatchLogsAPI
-	IAM  iamiface.IAMAPI
-	CF   cloudformationiface.CloudFormationAPI
-	SM   secretsmanageriface.SecretsManagerAPI
+	ECS ecsiface.ECSAPI
+	EC2 ec2iface.EC2API
+	ELB elbv2iface.ELBV2API
+	CW  cloudwatchlogsiface.CloudWatchLogsAPI
+	IAM iamiface.IAMAPI
+	CF  cloudformationiface.CloudFormationAPI
+	SM  secretsmanageriface.SecretsManagerAPI
 }
 
-func NewSDK(sess *session.Session) sdk {
+func newSDK(sess client.ConfigProvider) sdk {
 	return sdk{
 		ECS: ecs.New(sess),
 		EC2: ec2.New(sess),
@@ -177,7 +177,7 @@ func (s sdk) StackExists(ctx context.Context, name string) (bool, error) {
 
 func (s sdk) CreateStack(ctx context.Context, name string, template *cf.Template, parameters map[string]string) error {
 	logrus.Debug("Create CloudFormation stack")
-	json, err := Marshall(template)
+	json, err := marshall(template)
 	if err != nil {
 		return err
 	}
@@ -205,7 +205,7 @@ func (s sdk) CreateStack(ctx context.Context, name string, template *cf.Template
 
 func (s sdk) CreateChangeSet(ctx context.Context, name string, template *cf.Template, parameters map[string]string) (string, error) {
 	logrus.Debug("Create CloudFormation Changeset")
-	json, err := Marshall(template)
+	json, err := marshall(template)
 	if err != nil {
 		return "", err
 	}
@@ -258,9 +258,9 @@ func (s sdk) UpdateStack(ctx context.Context, changeset string) error {
 }
 
 const (
-	StackCreate = iota
-	StackUpdate
-	StackDelete
+	stackCreate = iota
+	stackUpdate
+	stackDelete
 )
 
 func (s sdk) WaitStackComplete(ctx context.Context, name string, operation int) error {
@@ -268,9 +268,9 @@ func (s sdk) WaitStackComplete(ctx context.Context, name string, operation int)
 		StackName: aws.String(name),
 	}
 	switch operation {
-	case StackCreate:
+	case stackCreate:
 		return s.CF.WaitUntilStackCreateCompleteWithContext(ctx, input)
-	case StackDelete:
+	case stackDelete:
 		return s.CF.WaitUntilStackDeleteCompleteWithContext(ctx, input)
 	default:
 		return fmt.Errorf("internal error: unexpected stack operation %d", operation)
@@ -322,14 +322,14 @@ func (s sdk) ListStackParameters(ctx context.Context, name string) (map[string]s
 	return parameters, nil
 }
 
-type StackResource struct {
+type stackResource struct {
 	LogicalID string
 	Type      string
 	ARN       string
 	Status    string
 }
 
-func (s sdk) ListStackResources(ctx context.Context, name string) ([]StackResource, error) {
+func (s sdk) ListStackResources(ctx context.Context, name string) ([]stackResource, error) {
 	// FIXME handle pagination
 	res, err := s.CF.ListStackResourcesWithContext(ctx, &cloudformation.ListStackResourcesInput{
 		StackName: aws.String(name),
@@ -338,9 +338,9 @@ func (s sdk) ListStackResources(ctx context.Context, name string) ([]StackResour
 		return nil, err
 	}
 
-	resources := []StackResource{}
+	resources := []stackResource{}
 	for _, r := range res.StackResourceSummaries {
-		resources = append(resources, StackResource{
+		resources = append(resources, stackResource{
 			LogicalID: aws.StringValue(r.LogicalResourceId),
 			Type:      aws.StringValue(r.ResourceType),
 			ARN:       aws.StringValue(r.PhysicalResourceId),
@@ -495,11 +495,11 @@ func (s sdk) DescribeServices(ctx context.Context, cluster string, arns []string
 			return nil, err
 		}
 		status = append(status, compose.ServiceStatus{
-			ID:            aws.StringValue(service.ServiceName),
-			Name:          name,
-			Replicas:      int(aws.Int64Value(service.RunningCount)),
-			Desired:       int(aws.Int64Value(service.DesiredCount)),
-			LoadBalancers: loadBalancers,
+			ID:         aws.StringValue(service.ServiceName),
+			Name:       name,
+			Replicas:   int(aws.Int64Value(service.RunningCount)),
+			Desired:    int(aws.Int64Value(service.DesiredCount)),
+			Publishers: loadBalancers,
 		})
 	}
 	return status, nil

+ 2 - 0
ecs/secrets/init.go

@@ -24,11 +24,13 @@ import (
 	"path/filepath"
 )
 
+// Secret define sensitive data to be bound as file
 type Secret struct {
 	Name string
 	Keys []string
 }
 
+// CreateSecretFiles retrieve sensitive data from env and store as plain text a a file in path
 func CreateSecretFiles(secret Secret, path string) error {
 	value, ok := os.LookupEnv(secret.Name)
 	if !ok {

+ 3 - 3
ecs/secrets/main/main.go

@@ -28,21 +28,21 @@ const secretsFolder = "/run/secrets"
 
 func main() {
 	if len(os.Args) != 2 {
-		fmt.Fprintf(os.Stderr, "usage: secrets <json encoded []Secret>")
+		fmt.Fprint(os.Stderr, "usage: secrets <json encoded []Secret>")
 		os.Exit(1)
 	}
 
 	var input []secrets.Secret
 	err := json.Unmarshal([]byte(os.Args[1]), &input)
 	if err != nil {
-		fmt.Fprintf(os.Stderr, err.Error())
+		fmt.Fprint(os.Stderr, err.Error())
 		os.Exit(1)
 	}
 
 	for _, secret := range input {
 		err := secrets.CreateSecretFiles(secret, secretsFolder)
 		if err != nil {
-			fmt.Fprintf(os.Stderr, err.Error())
+			fmt.Fprint(os.Stderr, err.Error())
 			os.Exit(1)
 		}
 	}

+ 10 - 10
ecs/up.go

@@ -67,20 +67,20 @@ func (b *ecsAPIService) Up(ctx context.Context, options *cli.ProjectOptions) err
 	}
 
 	parameters := map[string]string{
-		ParameterClusterName:     cluster,
-		ParameterVPCId:           vpc,
-		ParameterSubnet1Id:       subNets[0],
-		ParameterSubnet2Id:       subNets[1],
-		ParameterLoadBalancerARN: lb,
+		parameterClusterName:     cluster,
+		parameterVPCId:           vpc,
+		parameterSubnet1Id:       subNets[0],
+		parameterSubnet2Id:       subNets[1],
+		parameterLoadBalancerARN: lb,
 	}
 
 	update, err := b.SDK.StackExists(ctx, project.Name)
 	if err != nil {
 		return err
 	}
-	operation := StackCreate
+	operation := stackCreate
 	if update {
-		operation = StackUpdate
+		operation = stackUpdate
 		changeset, err := b.SDK.CreateChangeSet(ctx, project.Name, template, parameters)
 		if err != nil {
 			return err
@@ -110,7 +110,7 @@ func (b *ecsAPIService) Up(ctx context.Context, options *cli.ProjectOptions) err
 
 func (b ecsAPIService) GetVPC(ctx context.Context, project *types.Project) (string, error) {
 	//check compose file for custom VPC selected
-	if vpc, ok := project.Extensions[ExtensionVPC]; ok {
+	if vpc, ok := project.Extensions[extensionVPC]; ok {
 		vpcID := vpc.(string)
 		ok, err := b.SDK.VpcExists(ctx, vpcID)
 		if err != nil {
@@ -130,7 +130,7 @@ func (b ecsAPIService) GetVPC(ctx context.Context, project *types.Project) (stri
 
 func (b ecsAPIService) GetLoadBalancer(ctx context.Context, project *types.Project) (string, error) {
 	//check compose file for custom VPC selected
-	if ext, ok := project.Extensions[ExtensionLB]; ok {
+	if ext, ok := project.Extensions[extensionLB]; ok {
 		lb := ext.(string)
 		ok, err := b.SDK.LoadBalancerExists(ctx, lb)
 		if err != nil {
@@ -146,7 +146,7 @@ func (b ecsAPIService) GetLoadBalancer(ctx context.Context, project *types.Proje
 
 func (b ecsAPIService) GetCluster(ctx context.Context, project *types.Project) (string, error) {
 	//check compose file for custom VPC selected
-	if ext, ok := project.Extensions[ExtensionCluster]; ok {
+	if ext, ok := project.Extensions[extensionCluster]; ok {
 		cluster := ext.(string)
 		ok, err := b.SDK.ClusterExists(ctx, cluster)
 		if err != nil {

+ 5 - 5
ecs/wait.go

@@ -28,7 +28,7 @@ import (
 	"github.com/aws/aws-sdk-go/aws"
 )
 
-func (b *ecsAPIService) WaitStackCompletion(ctx context.Context, name string, operation int) error {
+func (b *ecsAPIService) WaitStackCompletion(ctx context.Context, name string, operation int) error { //nolint:gocyclo
 	knownEvents := map[string]struct{}{}
 	// progress writer
 	w := progress.ContextWriter(ctx)
@@ -76,23 +76,23 @@ func (b *ecsAPIService) WaitStackCompletion(ctx context.Context, name string, op
 
 			switch status {
 			case "CREATE_COMPLETE":
-				if operation == StackCreate {
+				if operation == stackCreate {
 					progressStatus = progress.Done
 
 				}
 			case "UPDATE_COMPLETE":
-				if operation == StackUpdate {
+				if operation == stackUpdate {
 					progressStatus = progress.Done
 				}
 			case "DELETE_COMPLETE":
-				if operation == StackDelete {
+				if operation == stackDelete {
 					progressStatus = progress.Done
 				}
 			default:
 				if strings.HasSuffix(status, "_FAILED") {
 					progressStatus = progress.Error
 					if stackErr == nil {
-						operation = StackDelete
+						operation = stackDelete
 						stackErr = fmt.Errorf(reason)
 					}
 				}

+ 11 - 11
ecs/x.go

@@ -17,15 +17,15 @@
 package ecs
 
 const (
-	ExtensionSecurityGroup   = "x-aws-securitygroup"
-	ExtensionVPC             = "x-aws-vpc"
-	ExtensionPullCredentials = "x-aws-pull_credentials"
-	ExtensionLB              = "x-aws-loadbalancer"
-	ExtensionCluster         = "x-aws-cluster"
-	ExtensionKeys            = "x-aws-keys"
-	ExtensionMinPercent      = "x-aws-min_percent"
-	ExtensionMaxPercent      = "x-aws-max_percent"
-	ExtensionRetention       = "x-aws-logs_retention"
-	ExtensionRole            = "x-aws-role"
-	ExtensionManagedPolicies = "x-aws-policies"
+	extensionSecurityGroup   = "x-aws-securitygroup"
+	extensionVPC             = "x-aws-vpc"
+	extensionPullCredentials = "x-aws-pull_credentials"
+	extensionLB              = "x-aws-loadbalancer"
+	extensionCluster         = "x-aws-cluster"
+	extensionKeys            = "x-aws-keys"
+	extensionMinPercent      = "x-aws-min_percent"
+	extensionMaxPercent      = "x-aws-max_percent"
+	extensionRetention       = "x-aws-logs_retention"
+	extensionRole            = "x-aws-role"
+	extensionManagedPolicies = "x-aws-policies"
 )

+ 4 - 0
secrets/api.go

@@ -29,6 +29,7 @@ type Service interface {
 	DeleteSecret(ctx context.Context, id string, recover bool) error
 }
 
+// Secret hold sensitive data
 type Secret struct {
 	ID          string            `json:"ID"`
 	Name        string            `json:"Name"`
@@ -38,6 +39,7 @@ type Secret struct {
 	password    string
 }
 
+// NewSecret builds a secret
 func NewSecret(name, username, password, description string) Secret {
 	return Secret{
 		Name:        name,
@@ -47,6 +49,7 @@ func NewSecret(name, username, password, description string) Secret {
 	}
 }
 
+// ToJSON marshall a Secret into JSON string
 func (s Secret) ToJSON() (string, error) {
 	b, err := json.MarshalIndent(&s, "", "\t")
 	if err != nil {
@@ -55,6 +58,7 @@ func (s Secret) ToJSON() (string, error) {
 	return string(b), nil
 }
 
+// GetCredString marshall a Secret's sensitive data into JSON string
 func (s Secret) GetCredString() (string, error) {
 	creds := map[string]string{
 		"username": s.username,