diff --git a/pkg/aws/ec2helpers.go b/pkg/aws/ec2helpers.go index 62610d84..1dd7cf1c 100644 --- a/pkg/aws/ec2helpers.go +++ b/pkg/aws/ec2helpers.go @@ -73,10 +73,9 @@ func (ac *awsCloud) filterByName(name string) types.Filter { return ec2Filter("tag:Name", ac.withAWSInfo(name)) } -func (ac *awsCloud) filterByCurrentClusterSubnet() types.Filter { - return ec2Filter(ac.withAWSInfo("tag:sigs.k8s.io/cluster-api-provider-aws/cluster/{infraID}"), "owned") -} - -func (ac *awsCloud) filterByCurrentClusterInstance() 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:sigs.k8s.io/cluster-api-provider-aws/cluster/{infraID}"), "owned"), + ec2Filter(ac.withAWSInfo("tag:kubernetes.io/cluster/{infraID}"), "owned"), + } } diff --git a/pkg/aws/gw-machineset.go b/pkg/aws/gw-machineset.go index a9354af3..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}}-node + - {{.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 8973ce19..a5706181 100644 --- a/pkg/aws/ocpgwdeployer.go +++ b/pkg/aws/ocpgwdeployer.go @@ -22,6 +22,7 @@ import ( "bytes" "context" "fmt" + "strings" "text/template" "github.com/aws/aws-sdk-go-v2/service/ec2" @@ -42,6 +43,8 @@ type ocpGatewayDeployer struct { } var PreferredInstances = []string{"c5d.large", "m5n.large"} +var nodeSGSuffix = "-worker-sg" +var controlPlaneSGSuffix = "-master-sg" // NewOcpGatewayDeployer returns a GatewayDeployer capable deploying gateways using OCP. // If the supplied cloud is not an awsCloud, an error is returned. @@ -69,18 +72,29 @@ func (d *ocpGatewayDeployer) Deploy(input api.GatewayDeployInput, status reporte status.Success(messageRetrievedVPCID, vpcID) - status.Start(messageValidatePrerequisites + "Deploy") + status.Start(messageValidatePrerequisites) publicSubnets, err := d.aws.findPublicSubnets(vpcID, d.aws.filterByName("{infraID}*-public-{region}*")) + + for i := range publicSubnets { + tags := publicSubnets[i].Tags + for i := range tags { + if strings.Contains(*tags[i].Key, "Name") { + if strings.Contains(*tags[i].Value, "subnet") { + nodeSGSuffix = "-node" + controlPlaneSGSuffix = "-controlplane" + } + } + } + } + if err != nil { return status.Error(err, "unable to find public subnets") } - status.Start("Creating Submariner gateway public subnet %v", publicSubnets) - - err = d.validateDeployPrerequisites(vpcID, input, publicSubnets, status) + err = d.validateDeployPrerequisites(vpcID, input, publicSubnets) if err != nil { - return status.Error(err, "unable to validate deploy prerequisites") + return status.Error(err, "unable to validate prerequisites") } status.Success(messageValidatedPrerequisites) @@ -92,7 +106,7 @@ func (d *ocpGatewayDeployer) Deploy(input api.GatewayDeployInput, status reporte status.Success("Created Submariner gateway security group %s", gatewaySG) - subnets, err := d.aws.getSubnetsSupportingInstanceType(publicSubnets, d.instanceType, nil) + subnets, err := d.aws.getSubnetsSupportingInstanceType(publicSubnets, d.instanceType) if err != nil { return status.Error(err, "unable to create security group") } @@ -143,29 +157,16 @@ func (d *ocpGatewayDeployer) Deploy(input api.GatewayDeployInput, status reporte } func (d *ocpGatewayDeployer) validateDeployPrerequisites(vpcID string, input api.GatewayDeployInput, - publicSubnets []types.Subnet, status reporter.Interface, + publicSubnets []types.Subnet, ) error { var errs []error var subnets []types.Subnet - status.Start("Validate security groups") - err := d.aws.validateCreateSecGroup(vpcID) - if err != nil { - status.Start("Validated security groups failed " + err.Error()) - } - status.Success("Validated security groups") - status.Start("Validate security groups rule for {infraID}-worker") - err = d.aws.validateCreateSecGroupRule(vpcID) - if err != nil { - status.Start("Validated security groups rule failed " + err.Error()) - } - err = d.aws.validateDescribeInstanceTypeOfferings() - if err != nil { - status.Start("validateDescribeInstanceTypeOfferings failed" + err.Error()) - } + errs = appendIfError(errs, d.aws.validateCreateSecGroup(vpcID)) + errs = appendIfError(errs, d.aws.validateCreateSecGroupRule(vpcID)) + err := d.aws.validateDescribeInstanceTypeOfferings() errs = appendIfError(errs, err) - status.Success("Validated security groups rule success") if err != nil { return utilerrors.NewAggregate(errs) } @@ -173,21 +174,17 @@ func (d *ocpGatewayDeployer) validateDeployPrerequisites(vpcID string, input api // If instanceType is not specified, auto-select the most suitable one. if d.instanceType == "" { for _, instanceType := range PreferredInstances { - status.Start("Getting Subnets %v", subnets) - subnets, err = d.aws.getSubnetsSupportingInstanceType(publicSubnets, instanceType, nil) + subnets, err = d.aws.getSubnetsSupportingInstanceType(publicSubnets, instanceType) if err != nil { return err } - status.Start("The subnet is %v", subnets) if len(subnets) != 0 { d.instanceType = instanceType break } } } else { - - status.Start("Getting Instance Type %v", d.instanceType) - subnets, err = d.aws.getSubnetsSupportingInstanceType(publicSubnets, d.instanceType, status) + subnets, err = d.aws.getSubnetsSupportingInstanceType(publicSubnets, d.instanceType) if err != nil { return err } @@ -214,18 +211,29 @@ 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.filterByCurrentClusterInstance(), - }, - }) - 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 { + return "", errors.Wrap(err, "error describing AWS instances") + } + + if len(result.Reservations) != 0 { + break + } } if len(result.Reservations) == 0 { @@ -261,6 +269,7 @@ func (d *ocpGatewayDeployer) loadGatewayYAML(gatewaySecurityGroup, amiID string, Region: d.aws.region, SecurityGroup: gatewaySecurityGroup, PublicSubnet: extractName(publicSubnet.Tags), + NodeSGSuffix: nodeSGSuffix, } err = tpl.Execute(&buf, tplVars) @@ -312,6 +321,21 @@ func (d *ocpGatewayDeployer) Cleanup(status reporter.Interface) error { return status.Error(err, "unable to retrieve the VPC ID") } + //TODO can be removed when we stop supporting versions < OCP 4.16 + publicSubnets, err := d.aws.findPublicSubnets(vpcID, d.aws.filterByName("{infraID}*-public-{region}*")) + + for i := range publicSubnets { + tags := publicSubnets[i].Tags + for i := range tags { + if strings.Contains(*tags[i].Key, "Name") { + if strings.Contains(*tags[i].Value, "subnet") { + nodeSGSuffix = "-node" + controlPlaneSGSuffix = "-controlplane" + } + } + } + } + status.Success(messageRetrievedVPCID, vpcID) status.Start(messageValidatePrerequisites) diff --git a/pkg/aws/securitygroups.go b/pkg/aws/securitygroups.go index 5e117668..0da63d26 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}-node") + workerGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}"+nodeSGSuffix) if err != nil { return err } - masterGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}-master-sg") + masterGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}"+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}-node") + workerGroup, err := ac.getSecurityGroup(vpcID, "{infraID}"+nodeSGSuffix) if err != nil { return err } - masterGroup, err := ac.getSecurityGroup(vpcID, "{infraID}-master-sg") + masterGroup, err := ac.getSecurityGroup(vpcID, "{infraID}"+controlPlaneSGSuffix) if err != nil { return err } diff --git a/pkg/aws/subnets.go b/pkg/aws/subnets.go index cdac7c93..8a112bed 100644 --- a/pkg/aws/subnets.go +++ b/pkg/aws/subnets.go @@ -20,8 +20,6 @@ package aws import ( "context" - "github.com/submariner-io/admiral/pkg/reporter" - "github.com/aws/aws-sdk-go-v2/service/ec2" "github.com/aws/aws-sdk-go-v2/service/ec2/types" "github.com/pkg/errors" @@ -56,21 +54,31 @@ 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.filterByCurrentClusterSubnet(), - 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") + } + + if len(result.Subnets) != 0 { + break + } - result, err := ac.client.DescribeSubnets(context.TODO(), &ec2.DescribeSubnetsInput{Filters: filters}) - if err != nil { - return nil, errors.Wrap(err, "error describing AWS subnets") } return result.Subnets, nil } -func (ac *awsCloud) getSubnetsSupportingInstanceType(subnets []types.Subnet, instanceType string, status reporter.Interface) ([]types.Subnet, error) { +func (ac *awsCloud) getSubnetsSupportingInstanceType(subnets []types.Subnet, instanceType string) ([]types.Subnet, error) { return filterSubnets(subnets, func(subnet *types.Subnet) (bool, error) { output, err := ac.client.DescribeInstanceTypeOfferings(context.TODO(), &ec2.DescribeInstanceTypeOfferingsInput{ LocationType: types.LocationTypeAvailabilityZone, diff --git a/pkg/aws/validations.go b/pkg/aws/validations.go index 853adbca..1efec893 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}-node") + workerGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}"+nodeSGSuffix) if err != nil { return err } @@ -90,9 +90,10 @@ func (ac *awsCloud) validateDescribeInstanceTypeOfferings() error { } func (ac *awsCloud) validateDeleteSecGroup(vpcID string) error { - workerGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}-node") + workerGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}"+nodeSGSuffix) if err != nil { return err + } input := &ec2.DeleteSecurityGroupInput{ @@ -106,7 +107,7 @@ func (ac *awsCloud) validateDeleteSecGroup(vpcID string) error { } func (ac *awsCloud) validateDeleteSecGroupRule(vpcID string) error { - workerGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}-node") + workerGroupID, err := ac.getSecurityGroupID(vpcID, "{infraID}"+nodeSGSuffix) if err != nil { return err } diff --git a/pkg/aws/vpcs.go b/pkg/aws/vpcs.go index ba548f75..5ed23230 100644 --- a/pkg/aws/vpcs.go +++ b/pkg/aws/vpcs.go @@ -20,22 +20,34 @@ package aws import ( "context" + "github.com/pkg/errors" "github.com/aws/aws-sdk-go-v2/service/ec2" "github.com/aws/aws-sdk-go-v2/service/ec2/types" - "github.com/pkg/errors" ) 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.filterByCurrentClusterInstance(), - } - 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 {