From f2493af4f2ac714571b2ab86a2adaf463088984f Mon Sep 17 00:00:00 2001 From: Pascal Euhus Date: Sun, 14 Feb 2021 20:22:41 +0100 Subject: [PATCH] classify vpc subnets Signed-off-by: Pascal Euhus --- ecs/aws.go | 2 +- ecs/awsResources.go | 26 +++++++++++++++----------- ecs/aws_mock.go | 4 ++-- ecs/sdk.go | 24 +++++++++++++++++------- ecs/volumes.go | 4 ++-- 5 files changed, 37 insertions(+), 23 deletions(-) diff --git a/ecs/aws.go b/ecs/aws.go index b9e85990b..b5fafbcab 100644 --- a/ecs/aws.go +++ b/ecs/aws.go @@ -69,7 +69,7 @@ type API interface { getURLWithPortMapping(ctx context.Context, targetGroupArns []string) ([]compose.PortPublisher, error) ListTasks(ctx context.Context, cluster string, family string) ([]string, error) GetPublicIPs(ctx context.Context, interfaces ...string) (map[string]string, error) - ResolveLoadBalancer(ctx context.Context, nameOrArn string) (awsResource, string, string, []awsResource, error) + ResolveLoadBalancer(ctx context.Context, nameOrArn string) (awsResource, string, string, vpcSubNets, error) GetLoadBalancerURL(ctx context.Context, arn string) (string, error) GetParameter(ctx context.Context, name string) (string, error) SecurityGroupExists(ctx context.Context, sg string) (bool, error) diff --git a/ecs/awsResources.go b/ecs/awsResources.go index c52b5cf5e..02021d8de 100644 --- a/ecs/awsResources.go +++ b/ecs/awsResources.go @@ -37,10 +37,16 @@ import ( "github.com/sirupsen/logrus" ) +// vpcSubNets classification +type vpcSubNets struct { + public []awsResource + private []awsResource +} + // awsResources hold the AWS component being used or created to support services definition type awsResources struct { vpc string // shouldn't this also be an awsResource ? - subnets []awsResource + subnets vpcSubNets cluster awsResource loadBalancer awsResource loadBalancerType string @@ -66,7 +72,7 @@ func (r *awsResources) allSecurityGroups() []string { func (r *awsResources) subnetsIDs() []string { var ids []string - for _, r := range r.subnets { + for _, r := range append(r.subnets.private, r.subnets.public...) { ids = append(ids, r.ID()) } return ids @@ -207,6 +213,7 @@ func (b *ecsAPIService) parseVPCExtension(ctx context.Context, project *types.Pr } var publicSubNets []awsResource + var privateSubNets []awsResource for _, subNet := range subNets { isPublic, err := b.aws.IsPublicSubnet(ctx, subNet.ID()) if err != nil { @@ -214,6 +221,8 @@ func (b *ecsAPIService) parseVPCExtension(ctx context.Context, project *types.Pr } if isPublic { publicSubNets = append(publicSubNets, subNet) + } else { + privateSubNets = append(privateSubNets, subNet) } } @@ -222,7 +231,8 @@ func (b *ecsAPIService) parseVPCExtension(ctx context.Context, project *types.Pr } r.vpc = vpc - r.subnets = subNets + r.subnets.public = publicSubNets + r.subnets.private = privateSubNets return nil } @@ -451,14 +461,8 @@ func (b *ecsAPIService) ensureLoadBalancer(r *awsResources, project *types.Proje } var publicSubNetIDs []string - for _, subNetID := range r.subnetsIDs() { - isPublic, err := b.aws.IsPublicSubnet(context.Background(), subNetID) - if err != nil { - return err - } - if isPublic { - publicSubNetIDs = append(publicSubNetIDs, subNetID) - } + for _, subNetID := range r.subnetsIDs() { + publicSubNetIDs = append(publicSubNetIDs, subNetID) } template.Resources["LoadBalancer"] = &elasticloadbalancingv2.LoadBalancer{ diff --git a/ecs/aws_mock.go b/ecs/aws_mock.go index d857cda1c..78f881390 100644 --- a/ecs/aws_mock.go +++ b/ecs/aws_mock.go @@ -604,13 +604,13 @@ func (mr *MockAPIMockRecorder) ResolveFileSystem(arg0, arg1 interface{}) *gomock } // ResolveLoadBalancer mocks base method -func (m *MockAPI) ResolveLoadBalancer(arg0 context.Context, arg1 string) (awsResource, string, string, []awsResource, error) { +func (m *MockAPI) ResolveLoadBalancer(arg0 context.Context, arg1 string) (awsResource, string, string, vpcSubNets, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ResolveLoadBalancer", arg0, arg1) ret0, _ := ret[0].(awsResource) ret1, _ := ret[1].(string) ret2, _ := ret[2].(string) - ret3, _ := ret[3].([]awsResource) + ret3, _ := ret[3].(vpcSubNets) ret4, _ := ret[4].(error) return ret0, ret1, ret2, ret3, ret4 } diff --git a/ecs/sdk.go b/ecs/sdk.go index 34ba88be6..bee6432d7 100644 --- a/ecs/sdk.go +++ b/ecs/sdk.go @@ -1045,7 +1045,7 @@ func (s sdk) GetPublicIPs(ctx context.Context, interfaces ...string) (map[string } } -func (s sdk) ResolveLoadBalancer(ctx context.Context, nameOrArn string) (awsResource, string, string, []awsResource, error) { +func (s sdk) ResolveLoadBalancer(ctx context.Context, nameOrArn string) (awsResource, string, string, vpcSubNets, error) { logrus.Debug("Check if LoadBalancer exists: ", nameOrArn) var arns []*string var names []*string @@ -1060,17 +1060,27 @@ func (s sdk) ResolveLoadBalancer(ctx context.Context, nameOrArn string) (awsReso Names: names, }) if err != nil { - return nil, "", "", nil, err + return nil, "", "", vpcSubNets{}, err } if len(lbs.LoadBalancers) == 0 { - return nil, "", "", nil, errors.Wrapf(errdefs.ErrNotFound, "load balancer %q does not exist", nameOrArn) + return nil, "", "", vpcSubNets{}, errors.Wrapf(errdefs.ErrNotFound, "load balancer %q does not exist", nameOrArn) } it := lbs.LoadBalancers[0] - var subNets []awsResource + var subNets vpcSubNets for _, az := range it.AvailabilityZones { - subNets = append(subNets, existingAWSResource{ - id: aws.StringValue(az.SubnetId), - }) + isPublic, err := s.IsPublicSubnet(ctx,aws.StringValue(az.SubnetId)); + if err != nil { + return nil, "", "", subNets, err + } + if isPublic { + subNets.public = append(subNets.public, existingAWSResource{ + id: aws.StringValue(az.SubnetId), + }) + } else { + subNets.private = append(subNets.private, existingAWSResource{ + id: aws.StringValue(az.SubnetId), + }) + } } return existingAWSResource{ arn: aws.StringValue(it.LoadBalancerArn), diff --git a/ecs/volumes.go b/ecs/volumes.go index df1a296f4..9d046dc36 100644 --- a/ecs/volumes.go +++ b/ecs/volumes.go @@ -32,7 +32,7 @@ import ( func (b *ecsAPIService) createNFSMountTarget(project *types.Project, resources awsResources, template *cloudformation.Template) { for volume := range project.Volumes { - for _, subnet := range resources.subnets { + for _, subnet := range append(resources.subnets.public, resources.subnets.private...) { name := fmt.Sprintf("%sNFSMountTargetOn%s", normalizeResourceName(volume), normalizeResourceName(subnet.ID())) template.Resources[name] = &efs.MountTarget{ FileSystemId: resources.filesystems[volume].ID(), @@ -45,7 +45,7 @@ func (b *ecsAPIService) createNFSMountTarget(project *types.Project, resources a func (b *ecsAPIService) mountTargets(volume string, resources awsResources) []string { var refs []string - for _, subnet := range resources.subnets { + for _, subnet := range append(resources.subnets.public, resources.subnets.private...) { refs = append(refs, fmt.Sprintf("%sNFSMountTargetOn%s", normalizeResourceName(volume), normalizeResourceName(subnet.ID()))) } return refs