-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2512 from wking/aws-metadata-caching
pkg/asset/installconfig/aws/metadata: Store AWS metadata
- Loading branch information
Showing
10 changed files
with
217 additions
and
170 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package aws | ||
|
||
import ( | ||
"context" | ||
|
||
"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/pkg/errors" | ||
) | ||
|
||
// availabilityZones retrieves a list of availability zones for the given region. | ||
func availabilityZones(ctx context.Context, session *session.Session, region string) ([]string, error) { | ||
client := ec2.New(session, aws.NewConfig().WithRegion(region)) | ||
resp, err := client.DescribeAvailabilityZonesWithContext(ctx, &ec2.DescribeAvailabilityZonesInput{ | ||
Filters: []*ec2.Filter{ | ||
{ | ||
Name: aws.String("region-name"), | ||
Values: []*string{aws.String(region)}, | ||
}, | ||
{ | ||
Name: aws.String("state"), | ||
Values: []*string{aws.String("available")}, | ||
}, | ||
}, | ||
}) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "fetching availability zones") | ||
} | ||
|
||
zones := []string{} | ||
for _, zone := range resp.AvailabilityZones { | ||
zones = append(zones, *zone.ZoneName) | ||
} | ||
|
||
if len(zones) == 0 { | ||
return nil, errors.Errorf("no available zones in %s", region) | ||
} | ||
|
||
return zones, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// Package aws collects AWS-specific configuration. | ||
package aws |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package aws | ||
|
||
import ( | ||
"context" | ||
"sync" | ||
|
||
"github.com/aws/aws-sdk-go/aws/session" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
// Metadata holds additional metadata for InstallConfig resources that | ||
// does not need to be user-supplied (e.g. because it can be retrieved | ||
// from external APIs). | ||
type Metadata struct { | ||
session *session.Session | ||
availabilityZones []string | ||
region string | ||
mutex sync.Mutex | ||
} | ||
|
||
// NewMetadata initializes a new Metadata object. | ||
func NewMetadata(region string) *Metadata { | ||
return &Metadata{region: region} | ||
} | ||
|
||
// Session holds an AWS session which can be used for AWS API calls | ||
// during asset generation. | ||
func (m *Metadata) Session(ctx context.Context) (*session.Session, error) { | ||
m.mutex.Lock() | ||
defer m.mutex.Unlock() | ||
|
||
return m.unlockedSession(ctx) | ||
} | ||
|
||
func (m *Metadata) unlockedSession(ctx context.Context) (*session.Session, error) { | ||
if m.session == nil { | ||
var err error | ||
m.session, err = GetSession() | ||
if err != nil { | ||
return nil, errors.Wrap(err, "creating AWS session") | ||
} | ||
} | ||
|
||
return m.session, nil | ||
} | ||
|
||
// AvailabilityZones retrieves a list of availability zones for the configured region. | ||
func (m *Metadata) AvailabilityZones(ctx context.Context) ([]string, error) { | ||
m.mutex.Lock() | ||
defer m.mutex.Unlock() | ||
|
||
if len(m.availabilityZones) == 0 { | ||
session, err := m.unlockedSession(ctx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
m.availabilityZones, err = availabilityZones(ctx, session, m.region) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "creating AWS session") | ||
} | ||
} | ||
|
||
return m.availabilityZones, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"sort" | ||
"strings" | ||
|
||
"github.com/openshift/installer/pkg/types/aws" | ||
"github.com/openshift/installer/pkg/types/aws/validation" | ||
"github.com/pkg/errors" | ||
"github.com/sirupsen/logrus" | ||
survey "gopkg.in/AlecAivazis/survey.v1" | ||
) | ||
|
||
// Platform collects AWS-specific configuration. | ||
func Platform() (*aws.Platform, error) { | ||
longRegions := make([]string, 0, len(validation.Regions)) | ||
shortRegions := make([]string, 0, len(validation.Regions)) | ||
for id, location := range validation.Regions { | ||
longRegions = append(longRegions, fmt.Sprintf("%s (%s)", id, location)) | ||
shortRegions = append(shortRegions, id) | ||
} | ||
regionTransform := survey.TransformString(func(s string) string { | ||
return strings.SplitN(s, " ", 2)[0] | ||
}) | ||
|
||
defaultRegion := "us-east-1" | ||
_, ok := validation.Regions[defaultRegion] | ||
if !ok { | ||
panic(fmt.Sprintf("installer bug: invalid default AWS region %q", defaultRegion)) | ||
} | ||
|
||
ssn, err := GetSession() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
defaultRegionPointer := ssn.Config.Region | ||
if defaultRegionPointer != nil && *defaultRegionPointer != "" { | ||
_, ok := validation.Regions[*defaultRegionPointer] | ||
if ok { | ||
defaultRegion = *defaultRegionPointer | ||
} else { | ||
logrus.Warnf("Unrecognized AWS region %q, defaulting to %s", *defaultRegionPointer, defaultRegion) | ||
} | ||
} | ||
|
||
sort.Strings(longRegions) | ||
sort.Strings(shortRegions) | ||
|
||
var region string | ||
err = survey.Ask([]*survey.Question{ | ||
{ | ||
Prompt: &survey.Select{ | ||
Message: "Region", | ||
Help: "The AWS region to be used for installation.", | ||
Default: fmt.Sprintf("%s (%s)", defaultRegion, validation.Regions[defaultRegion]), | ||
Options: longRegions, | ||
}, | ||
Validate: survey.ComposeValidators(survey.Required, func(ans interface{}) error { | ||
choice := regionTransform(ans).(string) | ||
i := sort.SearchStrings(shortRegions, choice) | ||
if i == len(shortRegions) || shortRegions[i] != choice { | ||
return errors.Errorf("invalid region %q", choice) | ||
} | ||
return nil | ||
}), | ||
Transform: regionTransform, | ||
}, | ||
}, ®ion) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &aws.Platform{ | ||
Region: region, | ||
}, nil | ||
} |
71 changes: 0 additions & 71 deletions
71
pkg/asset/installconfig/aws/aws.go → pkg/asset/installconfig/aws/session.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.