Explorar o código

Split long `Convert` func into smaller, focussed sub-func

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof %!s(int64=5) %!d(string=hai) anos
pai
achega
37177e6d7a
Modificáronse 1 ficheiros con 159 adicións e 125 borrados
  1. 159 125
      ecs/pkg/amazon/cloudformation.go

+ 159 - 125
ecs/pkg/amazon/cloudformation.go

@@ -69,17 +69,7 @@ func (c client) Convert(project *compose.Project) (*cloudformation.Template, err
 	// Create Cluster is `ParameterClusterName` parameter is not set
 	template.Conditions["CreateCluster"] = cloudformation.Equals("", cloudformation.Ref(ParameterClusterName))
 
-	template.Resources["Cluster"] = &ecs.Cluster{
-		ClusterName: project.Name,
-		Tags: []tags.Tag{
-			{
-				Key:   ProjectTag,
-				Value: project.Name,
-			},
-		},
-		AWSCloudFormationCondition: "CreateCluster",
-	}
-	cluster := cloudformation.If("CreateCluster", cloudformation.Ref("Cluster"), cloudformation.Ref(ParameterClusterName))
+	cluster := c.createCluster(project, template)
 
 	networks := map[string]string{}
 	for _, net := range project.Networks {
@@ -92,34 +82,8 @@ func (c client) Convert(project *compose.Project) (*cloudformation.Template, err
 	}
 
 	// Private DNS namespace will allow DNS name for the services to be <service>.<project>.local
-	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),
-	}
-
-	loadBalancerType := "network"
-	loadBalancerName := fmt.Sprintf(
-		"%s%sLB",
-		strings.Title(project.Name),
-		strings.ToUpper(loadBalancerType[0:1]),
-	)
-	loadBalancer := &elasticloadbalancingv2.LoadBalancer{
-		Name:   loadBalancerName,
-		Scheme: "internet-facing",
-		Subnets: []string{
-			cloudformation.Ref(ParameterSubnet1Id),
-			cloudformation.Ref(ParameterSubnet2Id),
-		},
-		Tags: []tags.Tag{
-			{
-				Key:   ProjectTag,
-				Value: project.Name,
-			},
-		},
-		Type: loadBalancerType,
-	}
-	template.Resources[loadBalancerName] = loadBalancer
+	c.createCloudMap(project, template)
+	loadBalancer := c.createLoadBalancer(project, template)
 
 	for _, service := range project.Services {
 		definition, err := Convert(project, service)
@@ -127,30 +91,13 @@ func (c client) Convert(project *compose.Project) (*cloudformation.Template, err
 			return nil, err
 		}
 
-		taskExecutionRole := fmt.Sprintf("%sTaskExecutionRole", normalizeResourceName(service.Name))
-		policy, err := c.getPolicy(definition)
+		taskExecutionRole, err := c.createTaskExecutionRole(service, err, definition, template)
 		if err != nil {
-			return nil, err
-		}
-		rolePolicies := []iam.Role_Policy{}
-		if policy != nil {
-			rolePolicies = append(rolePolicies, iam.Role_Policy{
-				PolicyDocument: policy,
-				PolicyName:     fmt.Sprintf("%sGrantAccessToSecrets", service.Name),
-			})
-
+			return template, err
 		}
 		definition.ExecutionRoleArn = cloudformation.Ref(taskExecutionRole)
 
 		taskDefinition := fmt.Sprintf("%sTaskDefinition", normalizeResourceName(service.Name))
-		template.Resources[taskExecutionRole] = &iam.Role{
-			AssumeRolePolicyDocument: assumeRolePolicyDocument,
-			Policies:                 rolePolicies,
-			ManagedPolicyArns: []string{
-				ECSTaskExecutionPolicy,
-				ECRReadOnlyPolicy,
-			},
-		}
 		template.Resources[taskDefinition] = definition
 
 		var healthCheck *cloudmap.Service_HealthCheckConfig
@@ -158,26 +105,7 @@ func (c client) Convert(project *compose.Project) (*cloudformation.Template, err
 			// FIXME ECS only support HTTP(s) health checks, while Docker only support CMD
 		}
 
-		serviceRegistration := fmt.Sprintf("%sServiceDiscoveryEntry", normalizeResourceName(service.Name))
-		serviceRegistry := ecs.Service_ServiceRegistry{
-			RegistryArn: cloudformation.GetAtt(serviceRegistration, "Arn"),
-		}
-
-		template.Resources[serviceRegistration] = &cloudmap.Service{
-			Description:       fmt.Sprintf("%q service discovery entry in Cloud Map", service.Name),
-			HealthCheckConfig: healthCheck,
-			Name:              service.Name,
-			NamespaceId:       cloudformation.Ref("CloudMap"),
-			DnsConfig: &cloudmap.Service_DnsConfig{
-				DnsRecords: []cloudmap.Service_DnsRecord{
-					{
-						TTL:  60,
-						Type: cloudmapapi.RecordTypeA,
-					},
-				},
-				RoutingPolicy: cloudmapapi.RoutingPolicyMultivalue,
-			},
-		}
+		serviceRegistry := c.createServiceRegistry(service, template, healthCheck)
 
 		serviceSecurityGroups := []string{}
 		for net := range service.Networks {
@@ -188,54 +116,10 @@ func (c client) Convert(project *compose.Project) (*cloudformation.Template, err
 		serviceLB := []ecs.Service_LoadBalancer{}
 		if len(service.Ports) > 0 {
 			for _, port := range service.Ports {
-
-				protocolType := strings.ToUpper(port.Protocol)
-				targetGroupName := fmt.Sprintf(
-					"%s%s%sTargetGroup",
-					normalizeResourceName(service.Name),
-					strings.ToUpper(port.Protocol),
-					string(port.Published),
-				)
-				template.Resources[targetGroupName] = &elasticloadbalancingv2.TargetGroup{
-					Name:     targetGroupName,
-					Port:     int(port.Target),
-					Protocol: protocolType,
-					Tags: []tags.Tag{
-						{
-							Key:   ProjectTag,
-							Value: project.Name,
-						},
-					},
-					VpcId:      cloudformation.Ref(ParameterVPCId),
-					TargetType: elbv2.TargetTypeEnumIp,
-				}
-				listenerName := fmt.Sprintf(
-					"%s%s%sListener",
-					normalizeResourceName(service.Name),
-					strings.ToUpper(port.Protocol),
-					string(port.Published),
-				)
-				//add listener to dependsOn
-				//https://stackoverflow.com/questions/53971873/the-target-group-does-not-have-an-associated-load-balancer
+				protocol := strings.ToUpper(port.Protocol)
+				targetGroupName := c.createTargetGroup(project, service, port, template, protocol)
+				listenerName := c.createListener(service, port, template, targetGroupName, loadBalancer, protocol)
 				dependsOn = append(dependsOn, listenerName)
-				template.Resources[listenerName] = &elasticloadbalancingv2.Listener{
-					DefaultActions: []elasticloadbalancingv2.Listener_Action{
-						{
-							ForwardConfig: &elasticloadbalancingv2.Listener_ForwardConfig{
-								TargetGroups: []elasticloadbalancingv2.Listener_TargetGroupTuple{
-									{
-										TargetGroupArn: cloudformation.Ref(targetGroupName),
-									},
-								},
-							},
-							Type: elbv2.ActionTypeEnumForward,
-						},
-					},
-					LoadBalancerArn: cloudformation.Ref(loadBalancerName),
-					Protocol:        protocolType,
-					Port:            int(port.Published),
-				}
-
 				serviceLB = append(serviceLB, ecs.Service_LoadBalancer{
 					ContainerName:  service.Name,
 					ContainerPort:  int(port.Published),
@@ -287,6 +171,156 @@ func (c client) Convert(project *compose.Project) (*cloudformation.Template, err
 	return template, nil
 }
 
+func (c client) createLoadBalancer(project *compose.Project, template *cloudformation.Template) string {
+	loadBalancerType := "network"
+	loadBalancerName := fmt.Sprintf(
+		"%s%sLB",
+		strings.Title(project.Name),
+		strings.ToUpper(loadBalancerType[0:1]),
+	)
+	loadBalancer := &elasticloadbalancingv2.LoadBalancer{
+		Name:   loadBalancerName,
+		Scheme: "internet-facing",
+		Subnets: []string{
+			cloudformation.Ref(ParameterSubnet1Id),
+			cloudformation.Ref(ParameterSubnet2Id),
+		},
+		Tags: []tags.Tag{
+			{
+				Key:   ProjectTag,
+				Value: project.Name,
+			},
+		},
+		Type: loadBalancerType,
+	}
+	template.Resources[loadBalancerName] = loadBalancer
+	return loadBalancerName
+}
+
+func (c client) createListener(service types.ServiceConfig, port types.ServicePortConfig, template *cloudformation.Template, targetGroupName string, loadBalancerName string, protocol string) string {
+	listenerName := fmt.Sprintf(
+		"%s%s%sListener",
+		normalizeResourceName(service.Name),
+		strings.ToUpper(port.Protocol),
+		string(port.Published),
+	)
+	//add listener to dependsOn
+	//https://stackoverflow.com/questions/53971873/the-target-group-does-not-have-an-associated-load-balancer
+	template.Resources[listenerName] = &elasticloadbalancingv2.Listener{
+		DefaultActions: []elasticloadbalancingv2.Listener_Action{
+			{
+				ForwardConfig: &elasticloadbalancingv2.Listener_ForwardConfig{
+					TargetGroups: []elasticloadbalancingv2.Listener_TargetGroupTuple{
+						{
+							TargetGroupArn: cloudformation.Ref(targetGroupName),
+						},
+					},
+				},
+				Type: elbv2.ActionTypeEnumForward,
+			},
+		},
+		LoadBalancerArn: cloudformation.Ref(loadBalancerName),
+		Protocol:        protocol,
+		Port:            int(port.Published),
+	}
+	return listenerName
+}
+
+func (c client) createTargetGroup(project *compose.Project, service types.ServiceConfig, port types.ServicePortConfig, template *cloudformation.Template, protocol string) string {
+	targetGroupName := fmt.Sprintf(
+		"%s%s%sTargetGroup",
+		normalizeResourceName(service.Name),
+		strings.ToUpper(port.Protocol),
+		string(port.Published),
+	)
+	template.Resources[targetGroupName] = &elasticloadbalancingv2.TargetGroup{
+		Name:     targetGroupName,
+		Port:     int(port.Target),
+		Protocol: protocol,
+		Tags: []tags.Tag{
+			{
+				Key:   ProjectTag,
+				Value: project.Name,
+			},
+		},
+		VpcId:      cloudformation.Ref(ParameterVPCId),
+		TargetType: elbv2.TargetTypeEnumIp,
+	}
+	return targetGroupName
+}
+
+func (c client) createServiceRegistry(service types.ServiceConfig, template *cloudformation.Template, healthCheck *cloudmap.Service_HealthCheckConfig) ecs.Service_ServiceRegistry {
+	serviceRegistration := fmt.Sprintf("%sServiceDiscoveryEntry", normalizeResourceName(service.Name))
+	serviceRegistry := ecs.Service_ServiceRegistry{
+		RegistryArn: cloudformation.GetAtt(serviceRegistration, "Arn"),
+	}
+
+	template.Resources[serviceRegistration] = &cloudmap.Service{
+		Description:       fmt.Sprintf("%q service discovery entry in Cloud Map", service.Name),
+		HealthCheckConfig: healthCheck,
+		Name:              service.Name,
+		NamespaceId:       cloudformation.Ref("CloudMap"),
+		DnsConfig: &cloudmap.Service_DnsConfig{
+			DnsRecords: []cloudmap.Service_DnsRecord{
+				{
+					TTL:  60,
+					Type: cloudmapapi.RecordTypeA,
+				},
+			},
+			RoutingPolicy: cloudmapapi.RoutingPolicyMultivalue,
+		},
+	}
+	return serviceRegistry
+}
+
+func (c client) createTaskExecutionRole(service types.ServiceConfig, err error, definition *ecs.TaskDefinition, template *cloudformation.Template) (string, error) {
+	taskExecutionRole := fmt.Sprintf("%sTaskExecutionRole", normalizeResourceName(service.Name))
+	policy, err := c.getPolicy(definition)
+	if err != nil {
+		return taskExecutionRole, err
+	}
+	rolePolicies := []iam.Role_Policy{}
+	if policy != nil {
+		rolePolicies = append(rolePolicies, iam.Role_Policy{
+			PolicyDocument: policy,
+			PolicyName:     fmt.Sprintf("%sGrantAccessToSecrets", service.Name),
+		})
+
+	}
+	template.Resources[taskExecutionRole] = &iam.Role{
+		AssumeRolePolicyDocument: assumeRolePolicyDocument,
+		Policies:                 rolePolicies,
+		ManagedPolicyArns: []string{
+			ECSTaskExecutionPolicy,
+			ECRReadOnlyPolicy,
+		},
+	}
+	return taskExecutionRole, nil
+}
+
+func (c client) createCluster(project *compose.Project, template *cloudformation.Template) string {
+	template.Resources["Cluster"] = &ecs.Cluster{
+		ClusterName: project.Name,
+		Tags: []tags.Tag{
+			{
+				Key:   ProjectTag,
+				Value: project.Name,
+			},
+		},
+		AWSCloudFormationCondition: "CreateCluster",
+	}
+	cluster := cloudformation.If("CreateCluster", cloudformation.Ref("Cluster"), cloudformation.Ref(ParameterClusterName))
+	return cluster
+}
+
+func (c client) createCloudMap(project *compose.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),
+	}
+}
+
 func convertNetwork(project *compose.Project, net types.NetworkConfig, vpc string, template *cloudformation.Template) string {
 	if sg, ok := net.Extras[ExtensionSecurityGroup]; ok {
 		logrus.Debugf("Security Group for network %q set by user to %q", net.Name, sg)