From 403173980ca04688f582b7cf4d13e1bea1cb34b3 Mon Sep 17 00:00:00 2001 From: Aswin Suryanarayanan Date: Mon, 17 Jun 2024 09:24:10 -0400 Subject: [PATCH] Fix AWS cloud prepare to support new naming convention OCP 4.16 has a new naming convnention, so cloud prepare is enhanced to support both old and new formats. Signed-off-by: Aswin Suryanarayanan --- pkg/aws/aws.go | 52 +++++++++++++++++++++++++++-- pkg/aws/ec2helpers.go | 7 ++-- pkg/aws/gw-machineset.go | 2 +- pkg/aws/gw-machineset.yaml.template | 2 +- pkg/aws/ocpgwdeployer.go | 44 ++++++++++++++++++------ pkg/aws/securitygroups.go | 8 ++--- pkg/aws/subnets.go | 26 ++++++++++----- pkg/aws/validations.go | 6 ++-- pkg/aws/vpcs.go | 24 +++++++++---- 9 files changed, 131 insertions(+), 40 deletions(-) diff --git a/pkg/aws/aws.go b/pkg/aws/aws.go index 67554174..68ed99d0 100644 --- a/pkg/aws/aws.go +++ b/pkg/aws/aws.go @@ -20,6 +20,9 @@ package aws import ( "context" + "fmt" + "regexp" + "strings" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" @@ -38,9 +41,11 @@ const ( ) type awsCloud struct { - client awsClient.Interface - infraID string - region string + client awsClient.Interface + infraID string + region string + nodeSGSuffix string + controlPlaneSGSuffix string } // NewCloud creates a new api.Cloud instance which can prepare AWS for Submariner to be deployed on it. @@ -88,6 +93,37 @@ func DefaultProfile() string { return "default" } +func (ac *awsCloud) setSuffixes(vpcID string) error { + if ac.nodeSGSuffix != "" { + return nil + } + + publicSubnets, err := ac.findPublicSubnets(vpcID, ac.filterByName("{infraID}*-public-{region}*")) + if err != nil || len(publicSubnets) == 0 { + return errors.Wrapf(err, "unable to find the public subnet") + } + + pattern := fmt.Sprintf(`%s.*-subnet-public-%s.*`, regexp.QuoteMeta(ac.infraID), regexp.QuoteMeta(ac.region)) + re := regexp.MustCompile(pattern) + + for i := range publicSubnets { + tags := publicSubnets[i].Tags + for i := range tags { + if strings.Contains(*tags[i].Key, "Name") && re.MatchString(*tags[i].Value) { + ac.nodeSGSuffix = "-node" + ac.controlPlaneSGSuffix = "-controlplane" + + return nil + } + } + } + + ac.nodeSGSuffix = "-worker-sg" + ac.controlPlaneSGSuffix = "-master-sg" + + return nil +} + func (ac *awsCloud) OpenPorts(ports []api.PortSpec, status reporter.Interface) error { status.Start(messageRetrieveVPCID) defer status.End() @@ -97,6 +133,11 @@ func (ac *awsCloud) OpenPorts(ports []api.PortSpec, status reporter.Interface) e return status.Error(err, "unable to retrieve the VPC ID") } + err = ac.setSuffixes(vpcID) + if err != nil { + return status.Error(err, "unable to retrieve the security group names") + } + status.Success(messageRetrievedVPCID, vpcID) status.Start(messageValidatePrerequisites) @@ -135,6 +176,11 @@ func (ac *awsCloud) ClosePorts(status reporter.Interface) error { return status.Error(err, "unable to retrieve the VPC ID") } + err = ac.setSuffixes(vpcID) + if err != nil { + return status.Error(err, "unable to retrieve the security group names") + } + status.Success(messageRetrievedVPCID, vpcID) status.Start(messageValidatePrerequisites) diff --git a/pkg/aws/ec2helpers.go b/pkg/aws/ec2helpers.go index 3f391d10..b3df80af 100644 --- a/pkg/aws/ec2helpers.go +++ b/pkg/aws/ec2helpers.go @@ -73,6 +73,9 @@ func (ac *awsCloud) filterByName(name string) types.Filter { return ec2Filter("tag:Name", ac.withAWSInfo(name)) } -func (ac *awsCloud) filterByCurrentCluster() types.Filter { - return ec2Filter(ac.withAWSInfo("tag:kubernetes.io/cluster/{infraID}"), "owned") +func (ac *awsCloud) filterByCurrentCluster() []types.Filter { + return []types.Filter{ + ec2Filter(ac.withAWSInfo("tag:kubernetes.io/cluster/{infraID}"), "owned"), + ec2Filter(ac.withAWSInfo("tag:sigs.k8s.io/cluster-api-provider-aws/cluster/{infraID}"), "owned"), + } } diff --git a/pkg/aws/gw-machineset.go b/pkg/aws/gw-machineset.go index 239390b6..892f1966 100644 --- a/pkg/aws/gw-machineset.go +++ b/pkg/aws/gw-machineset.go @@ -65,7 +65,7 @@ spec: - filters: - name: tag:Name values: - - {{.InfraID}}-worker-sg + - {{.InfraID}}{{.NodeSGSuffix}} - {{.SecurityGroup}} subnet: filters: diff --git a/pkg/aws/gw-machineset.yaml.template b/pkg/aws/gw-machineset.yaml.template index fb8d0368..8672d153 100644 --- a/pkg/aws/gw-machineset.yaml.template +++ b/pkg/aws/gw-machineset.yaml.template @@ -46,7 +46,7 @@ spec: - filters: - name: tag:Name values: - - {{.InfraID}}-worker-sg + - {{.InfraID}}{{.NodeSGSuffix}} - {{.SecurityGroup}} subnet: filters: diff --git a/pkg/aws/ocpgwdeployer.go b/pkg/aws/ocpgwdeployer.go index d658939b..5ec4ee84 100644 --- a/pkg/aws/ocpgwdeployer.go +++ b/pkg/aws/ocpgwdeployer.go @@ -69,9 +69,14 @@ func (d *ocpGatewayDeployer) Deploy(input api.GatewayDeployInput, status reporte status.Success(messageRetrievedVPCID, vpcID) + err = d.aws.setSuffixes(vpcID) + if err != nil { + return status.Error(err, "unable to retrieve the security group names") + } + status.Start(messageValidatePrerequisites) - publicSubnets, err := d.aws.findPublicSubnets(vpcID, d.aws.filterByName("{infraID}-public-{region}*")) + publicSubnets, err := d.aws.findPublicSubnets(vpcID, d.aws.filterByName("{infraID}*-public-{region}*")) if err != nil { return status.Error(err, "unable to find public subnets") } @@ -198,21 +203,32 @@ type machineSetConfig struct { Region string SecurityGroup string PublicSubnet string + NodeSGSuffix string } func (d *ocpGatewayDeployer) findAMIID(vpcID string) (string, error) { - result, err := d.aws.client.DescribeInstances(context.TODO(), &ec2.DescribeInstancesInput{ - Filters: []types.Filter{ - ec2Filter("vpc-id", vpcID), - d.aws.filterByName("{infraID}-worker*"), - d.aws.filterByCurrentCluster(), - }, - }) - if err != nil { - return "", errors.Wrap(err, "error describing AWS instances") + ownedFilters := d.aws.filterByCurrentCluster() + var err error + var result *ec2.DescribeInstancesOutput + + for i := range ownedFilters { + result, err = d.aws.client.DescribeInstances(context.TODO(), &ec2.DescribeInstancesInput{ + Filters: []types.Filter{ + ec2Filter("vpc-id", vpcID), + d.aws.filterByName("{infraID}-worker*"), + ownedFilters[i], + }, + }) + if err != nil { + continue + } + + if len(result.Reservations) != 0 { + break + } } - if len(result.Reservations) == 0 { + if err != nil || len(result.Reservations) == 0 { return "", newNotFoundError("reservations") } @@ -245,6 +261,7 @@ func (d *ocpGatewayDeployer) loadGatewayYAML(gatewaySecurityGroup, amiID string, Region: d.aws.region, SecurityGroup: gatewaySecurityGroup, PublicSubnet: extractName(publicSubnet.Tags), + NodeSGSuffix: d.aws.nodeSGSuffix, } err = tpl.Execute(&buf, tplVars) @@ -298,6 +315,11 @@ func (d *ocpGatewayDeployer) Cleanup(status reporter.Interface) error { status.Success(messageRetrievedVPCID, vpcID) + err = d.aws.setSuffixes(vpcID) + if err != nil { + return status.Error(err, "unable to retrieve the security group names") + } + status.Start(messageValidatePrerequisites) err = d.validateCleanupPrerequisites(vpcID) diff --git a/pkg/aws/securitygroups.go b/pkg/aws/securitygroups.go index b7f83452..ce361aac 100644 --- a/pkg/aws/securitygroups.go +++ b/pkg/aws/securitygroups.go @@ -97,12 +97,12 @@ func (ac *awsCloud) createClusterSGRule(srcGroup, destGroup *string, port uint16 } func (ac *awsCloud) allowPortInCluster(vpcID string, port uint16, protocol string) error { - workerGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}-worker-sg") + workerGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}"+ac.nodeSGSuffix) if err != nil { return err } - masterGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}-master-sg") + masterGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}"+ac.controlPlaneSGSuffix) if err != nil { return err } @@ -219,12 +219,12 @@ func (ac *awsCloud) deleteGatewaySG(vpcID string) error { } func (ac *awsCloud) revokePortsInCluster(vpcID string) error { - workerGroup, err := ac.getSecurityGroup(vpcID, "{infraID}-worker-sg") + workerGroup, err := ac.getSecurityGroup(vpcID, "{infraID}"+ac.nodeSGSuffix) if err != nil { return err } - masterGroup, err := ac.getSecurityGroup(vpcID, "{infraID}-master-sg") + masterGroup, err := ac.getSecurityGroup(vpcID, "{infraID}"+ac.controlPlaneSGSuffix) if err != nil { return err } diff --git a/pkg/aws/subnets.go b/pkg/aws/subnets.go index bf52dee2..7748d575 100644 --- a/pkg/aws/subnets.go +++ b/pkg/aws/subnets.go @@ -55,15 +55,25 @@ func subnetTagged(subnet *types.Subnet) bool { } func (ac *awsCloud) findPublicSubnets(vpcID string, filter types.Filter) ([]types.Subnet, error) { - filters := []types.Filter{ - ec2Filter("vpc-id", vpcID), - ac.filterByCurrentCluster(), - filter, - } + ownedFilters := ac.filterByCurrentCluster() + var err error + var result *ec2.DescribeSubnetsOutput + + for i := range ownedFilters { + filters := []types.Filter{ + ec2Filter("vpc-id", vpcID), + ownedFilters[i], + filter, + } + + result, err = ac.client.DescribeSubnets(context.TODO(), &ec2.DescribeSubnetsInput{Filters: filters}) + if err != nil { + return nil, errors.Wrap(err, "error describing AWS subnets") + } - result, err := ac.client.DescribeSubnets(context.TODO(), &ec2.DescribeSubnetsInput{Filters: filters}) - if err != nil { - return nil, errors.Wrap(err, "error describing AWS subnets") + if len(result.Subnets) != 0 { + break + } } return result.Subnets, nil diff --git a/pkg/aws/validations.go b/pkg/aws/validations.go index b48dd7b4..65ab1c62 100644 --- a/pkg/aws/validations.go +++ b/pkg/aws/validations.go @@ -54,7 +54,7 @@ func (ac *awsCloud) validateCreateSecGroup(vpcID string) error { } func (ac *awsCloud) validateCreateSecGroupRule(vpcID string) error { - workerGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}-worker-sg") + workerGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}"+ac.nodeSGSuffix) if err != nil { return err } @@ -90,7 +90,7 @@ func (ac *awsCloud) validateDescribeInstanceTypeOfferings() error { } func (ac *awsCloud) validateDeleteSecGroup(vpcID string) error { - workerGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}-worker-sg") + workerGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}"+ac.nodeSGSuffix) if err != nil { return err } @@ -106,7 +106,7 @@ func (ac *awsCloud) validateDeleteSecGroup(vpcID string) error { } func (ac *awsCloud) validateDeleteSecGroupRule(vpcID string) error { - workerGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}-worker-sg") + workerGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}"+ac.nodeSGSuffix) if err != nil { return err } diff --git a/pkg/aws/vpcs.go b/pkg/aws/vpcs.go index 8e1e1847..8012cb32 100644 --- a/pkg/aws/vpcs.go +++ b/pkg/aws/vpcs.go @@ -27,15 +27,25 @@ import ( ) func (ac *awsCloud) getVpcID() (string, error) { + ownedFilters := ac.filterByCurrentCluster() + var err error + var result *ec2.DescribeVpcsOutput vpcName := ac.withAWSInfo("{infraID}-vpc") - filters := []types.Filter{ - ac.filterByName(vpcName), - ac.filterByCurrentCluster(), - } - result, err := ac.client.DescribeVpcs(context.TODO(), &ec2.DescribeVpcsInput{Filters: filters}) - if err != nil { - return "", errors.Wrap(err, "error describing AWS VPCs") + for i := range ownedFilters { + filters := []types.Filter{ + ac.filterByName(vpcName), + ownedFilters[i], + } + + result, err = ac.client.DescribeVpcs(context.TODO(), &ec2.DescribeVpcsInput{Filters: filters}) + if err != nil { + return "", errors.Wrap(err, "error describing AWS VPCs") + } + + if len(result.Vpcs) != 0 { + break + } } if len(result.Vpcs) == 0 {