Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 2 additions & 0 deletions pkg/asset/installconfig/aws/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package aws collects AWS-specific configuration.
package aws
78 changes: 78 additions & 0 deletions pkg/asset/installconfig/aws/platform.go
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,
},
}, &region)
if err != nil {
return nil, err
}

return &aws.Platform{
Region: region,
}, nil
}
Original file line number Diff line number Diff line change
@@ -1,91 +1,20 @@
// Package aws collects AWS-specific configuration.
package aws

import (
"fmt"
"os"
"path/filepath"
"sort"
"strings"

"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/defaults"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/openshift/installer/pkg/types/aws"
"github.com/openshift/installer/pkg/types/aws/validation"
"github.com/openshift/installer/pkg/version"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
survey "gopkg.in/AlecAivazis/survey.v1"
ini "gopkg.in/ini.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,
},
}, &region)
if err != nil {
return nil, err
}

return &aws.Platform{
Region: region,
}, nil
}

// GetSession returns an AWS session by checking credentials
// and, if no creds are found, asks for them and stores them on disk in a config file
func GetSession() (*session.Session, error) {
Expand Down
49 changes: 15 additions & 34 deletions pkg/asset/installconfig/installconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,23 +75,7 @@ func (a *InstallConfig) Generate(parents asset.Parents) error {
a.Config.GCP = platform.GCP
a.Config.BareMetal = platform.BareMetal

if err := a.setDefaults(); err != nil {
return errors.Wrap(err, "failed to set defaults for install config")
}

if err := validation.ValidateInstallConfig(a.Config, openstackvalidation.NewValidValuesFetcher()).ToAggregate(); err != nil {
return errors.Wrap(err, "invalid install config")
}

data, err := yaml.Marshal(a.Config)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would like to keep this part in the asset itself.

and finish could take *InstallConfig for better api.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would like to keep this part in the asset itself.

We currently marshal in Generate and in Load (presumably to capture any default injection so it doesn't need to get re-injected next time, it was added here). So I think it makes sense to have it in the shared finish helper, but can push it back up into the doubled Generate / Load logic if you prefer. Thoughts?

and finish could take *InstallConfig for better api.

You want func finish(a *InstallConfig, filename string) error instead of func (a *InstallConfig) finish(filename string) error? I don't see a benefit to a function over my current method, but I can reroll to use a function if you like. Just let me know that I'm reading your comment correctly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't care enough. It's fine as is.

if err != nil {
return errors.Wrap(err, "failed to Marshal InstallConfig")
}
a.File = &asset.File{
Filename: installConfigFilename,
Data: data,
}
return nil
return a.finish("")
}

// Name returns the human-friendly name of the asset.
Expand Down Expand Up @@ -124,37 +108,34 @@ func (a *InstallConfig) Load(f asset.FileFetcher) (found bool, err error) {
a.Config = config

// Upconvert any deprecated fields
if err := a.convert(); err != nil {
if err := conversion.ConvertInstallConfig(a.Config); err != nil {
return false, errors.Wrap(err, "failed to upconvert install config")
}

if err := a.setDefaults(); err != nil {
return false, errors.Wrap(err, "failed to set defaults for install config")
err = a.finish(installConfigFilename)
if err != nil {
return false, err
}
return true, nil
}

func (a *InstallConfig) finish(filename string) error {
defaults.SetInstallConfigDefaults(a.Config)

if err := validation.ValidateInstallConfig(a.Config, openstackvalidation.NewValidValuesFetcher()).ToAggregate(); err != nil {
return false, errors.Wrapf(err, "invalid %q file", installConfigFilename)
if filename == "" {
return errors.Wrap(err, "invalid install config")
}
return errors.Wrapf(err, "invalid %q file", filename)
}

data, err := yaml.Marshal(a.Config)
if err != nil {
return false, errors.Wrap(err, "failed to Marshal InstallConfig")
return errors.Wrap(err, "failed to Marshal InstallConfig")
}
a.File = &asset.File{
Filename: installConfigFilename,
Data: data,
}

return true, nil
}

func (a *InstallConfig) setDefaults() error {
defaults.SetInstallConfigDefaults(a.Config)
return nil
}

// convert converts possibly older versions of the install config to
// the current version, relocating deprecated fields.
func (a *InstallConfig) convert() error {
return conversion.ConvertInstallConfig(a.Config)
}