Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 22 additions & 25 deletions pkg/asset/installconfig/aws/availabilityzones.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"context"
"fmt"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/ec2"
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"

typesaws "github.com/openshift/installer/pkg/types/aws"
awsdefaults "github.com/openshift/installer/pkg/types/aws/defaults"
Expand Down Expand Up @@ -42,54 +42,51 @@ type Zone struct {
}

// describeAvailabilityZones retrieves a list of all zones for the given region.
func describeAvailabilityZones(ctx context.Context, session *session.Session, region string, zones []string) ([]*ec2.AvailabilityZone, error) {
client := ec2.New(session, aws.NewConfig().WithRegion(region))
func describeAvailabilityZones(ctx context.Context, client *ec2.Client, region string, zones []string) ([]ec2types.AvailabilityZone, error) {
input := &ec2.DescribeAvailabilityZonesInput{
AllAvailabilityZones: aws.Bool(true),
Filters: []*ec2.Filter{
Filters: []ec2types.Filter{
{
Name: aws.String("region-name"),
Values: []*string{aws.String(region)},
Values: []string{region},
},
{
Name: aws.String("state"),
Values: []*string{aws.String("available")},
Values: []string{"available"},
},
},
}
if len(zones) > 0 {
for _, zone := range zones {
input.ZoneNames = append(input.ZoneNames, aws.String(zone))
}
input.ZoneNames = zones
}
resp, err := client.DescribeAvailabilityZonesWithContext(ctx, input)
resp, err := client.DescribeAvailabilityZones(ctx, input)
if err != nil {
return nil, fmt.Errorf("fetching zones: %w", err)
return nil, fmt.Errorf("failed to get availability zones: %w", err)
}

return resp.AvailabilityZones, nil
}

// filterZonesByType retrieves a list of zones by a given ZoneType attribute within the region.
// ZoneType can be availability-zone, local-zone or wavelength-zone.
func filterZonesByType(ctx context.Context, session *session.Session, region, zoneType string) ([]string, error) {
azs, err := describeAvailabilityZones(ctx, session, region, []string{})
func filterZonesByType(ctx context.Context, client *ec2.Client, region, zoneType string) ([]string, error) {
azs, err := describeAvailabilityZones(ctx, client, region, []string{})
if err != nil {
return nil, fmt.Errorf("fetching %s: %w", zoneType, err)
return nil, fmt.Errorf("failed to filter zones by type %s: %w", zoneType, err)
}
zones := []string{}
for _, zone := range azs {
if aws.StringValue(zone.ZoneType) == zoneType {
zones = append(zones, aws.StringValue(zone.ZoneName))
if aws.ToString(zone.ZoneType) == zoneType {
zones = append(zones, aws.ToString(zone.ZoneName))
}
}

return zones, nil
}

// availabilityZones retrieves a list of zones type 'availability-zone' in the region.
func availabilityZones(ctx context.Context, session *session.Session, region string) ([]string, error) {
zones, err := filterZonesByType(ctx, session, region, typesaws.AvailabilityZoneType)
func availabilityZones(ctx context.Context, client *ec2.Client, region string) ([]string, error) {
zones, err := filterZonesByType(ctx, client, region, typesaws.AvailabilityZoneType)
if err != nil {
return nil, err
}
Expand All @@ -100,13 +97,13 @@ func availabilityZones(ctx context.Context, session *session.Session, region str
}

// edgeZones retrieves a list of zones type 'local-zone' and 'wavelength-zone' in the region.
func edgeZones(ctx context.Context, session *session.Session, region string) ([]string, error) {
localZones, err := filterZonesByType(ctx, session, region, typesaws.LocalZoneType)
func edgeZones(ctx context.Context, client *ec2.Client, region string) ([]string, error) {
localZones, err := filterZonesByType(ctx, client, region, typesaws.LocalZoneType)
if err != nil {
return nil, fmt.Errorf("unable to retrieve Local Zone names: %w", err)
}

wavelengthZones, err := filterZonesByType(ctx, session, region, typesaws.WavelengthZoneType)
wavelengthZones, err := filterZonesByType(ctx, client, region, typesaws.WavelengthZoneType)
if err != nil {
return nil, fmt.Errorf("unable to retrieve Wavelength Zone names: %w", err)
}
Expand All @@ -122,8 +119,8 @@ func edgeZones(ctx context.Context, session *session.Session, region string) ([]
}

// describeFilteredZones retrieves a list of all zones for the given region.
func describeFilteredZones(ctx context.Context, session *session.Session, region string, zones []string) ([]*ec2.AvailabilityZone, error) {
azs, err := describeAvailabilityZones(ctx, session, region, zones)
func describeFilteredZones(ctx context.Context, client *ec2.Client, region string, zones []string) ([]ec2types.AvailabilityZone, error) {
azs, err := describeAvailabilityZones(ctx, client, region, zones)
if err != nil {
return nil, fmt.Errorf("fetching %s: %w", zones, err)
}
Expand Down
44 changes: 13 additions & 31 deletions pkg/asset/installconfig/aws/ec2.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,63 +5,43 @@ import (
"fmt"
"time"

ec2v2 "github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/ec2"
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
)

// GetRegions get all regions that are accessible.
func GetRegions(ctx context.Context) ([]string, error) {
client, err := NewEC2Client(ctx, EndpointOptions{
// Pass the default region (used for survey purposes) as the region here. Without a region
// the DescribeRegions call will fail immediately.
Region: "us-east-1",
})
if err != nil {
return nil, fmt.Errorf("failed to create EC2 client: %w", err)
}

output, err := client.DescribeRegions(ctx, &ec2v2.DescribeRegionsInput{AllRegions: aws.Bool(true)})
func GetRegions(ctx context.Context, client *ec2.Client) ([]string, error) {
output, err := client.DescribeRegions(ctx, &ec2.DescribeRegionsInput{AllRegions: aws.Bool(true)})
if err != nil {
return nil, fmt.Errorf("failed to get all regions: %w", err)
}

regions := []string{}
for _, region := range output.Regions {
regions = append(regions, *region.RegionName)
regions = append(regions, aws.ToString(region.RegionName))
}
return regions, nil
}

// DescribeSecurityGroups returns the list of ec2 Security Groups that contain the group id and vpc id.
func DescribeSecurityGroups(ctx context.Context, session *session.Session, securityGroupIDs []string, region string) ([]*ec2.SecurityGroup, error) {
client := ec2.New(session, aws.NewConfig().WithRegion(region))

sgIDPtrs := []*string{}
for _, sgid := range securityGroupIDs {
sgid := sgid
sgIDPtrs = append(sgIDPtrs, &sgid)
}

func DescribeSecurityGroups(ctx context.Context, client *ec2.Client, securityGroupIDs []string) ([]ec2types.SecurityGroup, error) {
cctx, cancel := context.WithTimeout(ctx, 1*time.Minute)
defer cancel()

sgOutput, err := client.DescribeSecurityGroupsWithContext(cctx, &ec2.DescribeSecurityGroupsInput{GroupIds: sgIDPtrs})
sgOutput, err := client.DescribeSecurityGroups(cctx, &ec2.DescribeSecurityGroupsInput{GroupIds: securityGroupIDs})
if err != nil {
return nil, err
}
return sgOutput.SecurityGroups, nil
}

// DescribePublicIpv4Pool returns the ec2 public IPv4 Pool attributes from the given ID.
func DescribePublicIpv4Pool(ctx context.Context, session *session.Session, region string, poolID string) (*ec2.PublicIpv4Pool, error) {
client := ec2.New(session, aws.NewConfig().WithRegion(region))

func DescribePublicIpv4Pool(ctx context.Context, client *ec2.Client, poolID string) (*ec2types.PublicIpv4Pool, error) {
cctx, cancel := context.WithTimeout(ctx, 1*time.Minute)
defer cancel()

poolOutputs, err := client.DescribePublicIpv4PoolsWithContext(cctx, &ec2.DescribePublicIpv4PoolsInput{PoolIds: []*string{aws.String(poolID)}})
poolOutputs, err := client.DescribePublicIpv4Pools(cctx, &ec2.DescribePublicIpv4PoolsInput{PoolIds: []string{poolID}})
if err != nil {
return nil, err
}
Expand All @@ -72,5 +52,7 @@ func DescribePublicIpv4Pool(ctx context.Context, session *session.Session, regio
if len(poolOutputs.PublicIpv4Pools) > 1 {
return nil, fmt.Errorf("more than one Public IPv4 Pool: %s", poolID)
}
return poolOutputs.PublicIpv4Pools[0], nil

pool := poolOutputs.PublicIpv4Pools[0]
return &pool, nil
}
42 changes: 22 additions & 20 deletions pkg/asset/installconfig/aws/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ import (
"fmt"
"sync"

"github.com/IBM/ibm-cos-sdk-go/aws"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/ec2"
awssdk "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"

typesaws "github.com/openshift/installer/pkg/types/aws"
Expand Down Expand Up @@ -84,11 +83,12 @@ func (m *Metadata) AvailabilityZones(ctx context.Context) ([]string, error) {
defer m.mutex.Unlock()

if len(m.availabilityZones) == 0 {
session, err := m.unlockedSession(ctx)
client, err := m.EC2Client(ctx)
if err != nil {
return nil, err
}
m.availabilityZones, err = availabilityZones(ctx, session, m.Region)

m.availabilityZones, err = availabilityZones(ctx, client, m.Region)
if err != nil {
return nil, fmt.Errorf("error retrieving Availability Zones: %w", err)
}
Expand Down Expand Up @@ -127,12 +127,12 @@ func (m *Metadata) EdgeZones(ctx context.Context) ([]string, error) {
defer m.mutex.Unlock()

if len(m.edgeZones) == 0 {
session, err := m.unlockedSession(ctx)
client, err := m.EC2Client(ctx)
if err != nil {
return nil, err
}

m.edgeZones, err = edgeZones(ctx, session, m.Region)
m.edgeZones, err = edgeZones(ctx, client, m.Region)
if err != nil {
return nil, fmt.Errorf("getting Local Zones: %w", err)
}
Expand All @@ -154,53 +154,55 @@ func (m *Metadata) EdgeSubnets(ctx context.Context) (Subnets, error) {

// SetZoneAttributes retrieves AWS Zone attributes and update required fields in zones.
func (m *Metadata) SetZoneAttributes(ctx context.Context, zoneNames []string, zones Zones) error {
sess, err := m.Session(ctx)
client, err := m.EC2Client(ctx)
if err != nil {
return fmt.Errorf("unable to get aws session to populate zone details: %w", err)
return err
}
azs, err := describeFilteredZones(ctx, sess, m.Region, zoneNames)

azs, err := describeFilteredZones(ctx, client, m.Region, zoneNames)
if err != nil {
return fmt.Errorf("unable to filter zones: %w", err)
}

for _, az := range azs {
zoneName := awssdk.StringValue(az.ZoneName)
zoneName := aws.ToString(az.ZoneName)
if _, ok := zones[zoneName]; !ok {
zones[zoneName] = &Zone{Name: zoneName}
}
if zones[zoneName].GroupName == "" {
zones[zoneName].GroupName = awssdk.StringValue(az.GroupName)
zones[zoneName].GroupName = aws.ToString(az.GroupName)
}
if zones[zoneName].Type == "" {
zones[zoneName].Type = awssdk.StringValue(az.ZoneType)
zones[zoneName].Type = aws.ToString(az.ZoneType)
}
if az.ParentZoneName != nil {
zones[zoneName].ParentZoneName = awssdk.StringValue(az.ParentZoneName)
zones[zoneName].ParentZoneName = aws.ToString(az.ParentZoneName)
}
}
return nil
}

// AllZones return all the zones and it's attributes available on the region.
func (m *Metadata) AllZones(ctx context.Context) (Zones, error) {
sess, err := m.Session(ctx)
client, err := m.EC2Client(ctx)
if err != nil {
return nil, fmt.Errorf("unable to get aws session to populate zone details: %w", err)
return nil, err
}
azs, err := describeAvailabilityZones(ctx, sess, m.Region, []string{})

azs, err := describeAvailabilityZones(ctx, client, m.Region, []string{})
if err != nil {
return nil, fmt.Errorf("unable to gather availability zones: %w", err)
}
zoneDesc := make(Zones, len(azs))
for _, az := range azs {
zoneName := awssdk.StringValue(az.ZoneName)
zoneName := aws.ToString(az.ZoneName)
zoneDesc[zoneName] = &Zone{
Name: zoneName,
GroupName: awssdk.StringValue(az.GroupName),
Type: awssdk.StringValue(az.ZoneType),
GroupName: aws.ToString(az.GroupName),
Type: aws.ToString(az.ZoneType),
}
if az.ParentZoneName != nil {
zoneDesc[zoneName].ParentZoneName = awssdk.StringValue(az.ParentZoneName)
zoneDesc[zoneName].ParentZoneName = aws.ToString(az.ParentZoneName)
}
}
return zoneDesc, nil
Expand Down
14 changes: 13 additions & 1 deletion pkg/asset/installconfig/aws/regions.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,18 @@ const (
func knownPublicRegions(architecture types.Architecture) ([]string, error) {
required := rhcos.AMIRegions(architecture)

regions, err := GetRegions(context.Background())
ctx := context.Background()
client, err := NewEC2Client(ctx, EndpointOptions{
// Pass the default region (used for survey purposes) as the region here.
// Without a region, the DescribeRegions call will fail immediately.
// At this point, custom endpoints are unknown as they are not yet configured.
Region: "us-east-1",
})
if err != nil {
return nil, fmt.Errorf("failed to create EC2 client: %w", err)
}

regions, err := GetRegions(ctx, client)
if err != nil {
return nil, fmt.Errorf("failed to get aws regions: %w", err)
}
Expand All @@ -47,6 +58,7 @@ func IsKnownPublicRegion(region string, architecture types.Architecture) (bool,
}

// IsSecretRegion determines if the region is part of a secret partition.
// Note: This uses the v1 EndpointResolver, which exposes the partition ID.
func IsSecretRegion(region string) (bool, error) {
endpoint, err := ec2.NewDefaultEndpointResolver().ResolveEndpoint(region, ec2.EndpointResolverOptions{})
if err != nil {
Expand Down
Loading