pkg/awsutil/account.go
package awsutil
import (
"fmt"
"strings"
"github.com/gotidy/ptr"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/ekristen/aws-nuke/v3/pkg/config"
)
type Account struct {
*Credentials
id string
arn string
userID string
aliases []string
regions []string
disabledRegions []string
}
func NewAccount(creds *Credentials, endpoints config.CustomEndpoints) (*Account, error) {
creds.CustomEndpoints = endpoints
account := Account{
Credentials: creds,
}
customStackSupportSTSAndIAM := true
if endpoints.GetRegion(DefaultRegionID) != nil {
if endpoints.GetURL(DefaultRegionID, "sts") == "" {
customStackSupportSTSAndIAM = false
} else if endpoints.GetURL(DefaultRegionID, "iam") == "" {
customStackSupportSTSAndIAM = false
}
}
if !customStackSupportSTSAndIAM {
account.id = "account-id-of-custom-region-" + DefaultRegionID
account.aliases = []string{account.id}
return &account, nil
}
defaultSession, err := account.NewSession(DefaultRegionID, "")
if err != nil {
return nil, errors.Wrapf(err, "failed to create default session in %s", DefaultRegionID)
}
identityOutput, err := sts.New(defaultSession).GetCallerIdentity(nil)
if err != nil {
return nil, errors.Wrap(err, "failed get caller identity")
}
regionsOutput, err := ec2.New(defaultSession).DescribeRegions(&ec2.DescribeRegionsInput{
AllRegions: ptr.Bool(true),
})
if err != nil {
return nil, errors.Wrap(err, "failed to get regions")
}
globalSession, err := account.NewSession(GlobalRegionID, "")
if err != nil {
return nil, errors.Wrapf(err, "failed to create global session in %s", GlobalRegionID)
}
aliasesOutput, err := iam.New(globalSession).ListAccountAliases(nil)
if err != nil {
return nil, errors.Wrap(err, "failed get account alias")
}
var aliases []string
for _, alias := range aliasesOutput.AccountAliases {
if alias != nil {
aliases = append(aliases, *alias)
}
}
regions := []string{"global"}
var disabledRegions []string
for _, region := range regionsOutput.Regions {
logrus.Debugf("region: %s, status: %s",
ptr.ToString(region.RegionName), ptr.ToString(region.OptInStatus))
if ptr.ToString(region.OptInStatus) == "not-opted-in" {
disabledRegions = append(disabledRegions, *region.RegionName)
} else {
regions = append(regions, *region.RegionName)
}
}
account.id = ptr.ToString(identityOutput.Account)
account.arn = ptr.ToString(identityOutput.Arn)
account.userID = ptr.ToString(identityOutput.UserId)
account.aliases = aliases
account.regions = regions
account.disabledRegions = disabledRegions
return &account, nil
}
// ID returns the account ID
func (a *Account) ID() string {
return a.id
}
// ARN returns the STS Authenticated ARN for the account
func (a *Account) ARN() string {
return a.arn
}
// UserID returns the authenticated user ID
func (a *Account) UserID() string {
return a.userID
}
// Alias returns the first alias for the account
func (a *Account) Alias() string {
if len(a.aliases) == 0 {
return fmt.Sprintf("no-alias-%s", a.ID())
}
return a.aliases[0]
}
// Aliases returns the list of aliases for the account
func (a *Account) Aliases() []string {
return a.aliases
}
func (a *Account) ResourceTypeToServiceType(regionName, resourceType string) string {
customRegion := a.CustomEndpoints.GetRegion(regionName)
if customRegion == nil {
return "-" // standard public AWS.
}
for _, e := range customRegion.Services {
if strings.HasPrefix(strings.ToLower(resourceType), e.Service) {
return e.Service
}
}
return ""
}
// Regions returns the list of regions that are enabled for the account
func (a *Account) Regions() []string {
return a.regions
}
// DisabledRegions returns the list of regions that are disabled for the account
func (a *Account) DisabledRegions() []string {
return a.disabledRegions
}