-
Notifications
You must be signed in to change notification settings - Fork 92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use local aws config in cli to get account and regions #7758
Changes from 9 commits
94d35f7
c5daf45
2dbd80d
447a664
b9ecbfe
0162b86
f369b4b
9d30463
a195ad1
e608a44
77004be
8c95e50
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ package aws | |
import ( | ||
"context" | ||
|
||
"github.com/aws/aws-sdk-go-v2/credentials" | ||
"github.com/aws/aws-sdk-go-v2/config" | ||
"github.com/aws/aws-sdk-go-v2/service/ec2" | ||
"github.com/aws/aws-sdk-go-v2/service/sts" | ||
) | ||
|
@@ -28,9 +28,9 @@ import ( | |
// Client is an interface that abstracts `rad init`'s interactions with AWS. This is for testing purposes. This is only exported because mockgen requires it. | ||
type Client interface { | ||
// GetCallerIdentity gets information about the provided credentials. | ||
GetCallerIdentity(ctx context.Context, region string, accessKeyID string, secretAccessKey string) (*sts.GetCallerIdentityOutput, error) | ||
GetCallerIdentity(ctx context.Context) (*sts.GetCallerIdentityOutput, error) | ||
// ListRegions lists the AWS regions available (fetched from EC2.DescribeRegions API). | ||
ListRegions(ctx context.Context, region string, accessKeyID string, secretAccessKey string) (*ec2.DescribeRegionsOutput, error) | ||
ListRegions(ctx context.Context) (*ec2.DescribeRegionsOutput, error) | ||
} | ||
|
||
// NewClient returns a new Client. | ||
|
@@ -43,12 +43,16 @@ type client struct{} | |
var _ Client = &client{} | ||
|
||
// GetCallerIdentity gets information about the provided credentials. | ||
func (c *client) GetCallerIdentity(ctx context.Context, region string, accessKeyID string, secretAccessKey string) (*sts.GetCallerIdentityOutput, error) { | ||
credentialsProvider := credentials.NewStaticCredentialsProvider(accessKeyID, secretAccessKey, "") | ||
stsClient := sts.New(sts.Options{ | ||
Region: region, | ||
Credentials: credentialsProvider, | ||
}) | ||
func (c *client) GetCallerIdentity(ctx context.Context) (*sts.GetCallerIdentityOutput, error) { | ||
// Load the AWS SDK config and credentials | ||
cfg, err := config.LoadDefaultConfig(ctx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Create an STS client | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is an STS Client? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Security Token Service Client and it is generally used when short-term access is needed to privileged AWS resources |
||
stsClient := sts.NewFromConfig(cfg) | ||
|
||
result, err := stsClient.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{}) | ||
if err != nil { | ||
return nil, err | ||
|
@@ -58,12 +62,16 @@ func (c *client) GetCallerIdentity(ctx context.Context, region string, accessKey | |
} | ||
|
||
// ListRegions lists the AWS regions available (fetched from EC2.DescribeRegions API). | ||
func (c *client) ListRegions(ctx context.Context, region string, accessKeyID string, secretAccessKey string) (*ec2.DescribeRegionsOutput, error) { | ||
credentialsProvider := credentials.NewStaticCredentialsProvider(accessKeyID, secretAccessKey, "") | ||
ec2Client := ec2.New(ec2.Options{ | ||
Region: region, | ||
Credentials: credentialsProvider, | ||
}) | ||
func (c *client) ListRegions(ctx context.Context) (*ec2.DescribeRegionsOutput, error) { | ||
// Load the AWS SDK config and credentials | ||
cfg, err := config.LoadDefaultConfig(ctx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Create an EC2 client | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if we need these comments. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. removed it |
||
ec2Client := ec2.NewFromConfig(cfg) | ||
|
||
result, err := ec2Client.DescribeRegions(ctx, &ec2.DescribeRegionsInput{}) | ||
if err != nil { | ||
return nil, err | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -18,6 +18,7 @@ package radinit | |||||
|
||||||
import ( | ||||||
"context" | ||||||
"fmt" | ||||||
|
||||||
"github.com/aws/aws-sdk-go-v2/service/ec2" | ||||||
"github.com/charmbracelet/bubbles/textinput" | ||||||
|
@@ -27,15 +28,15 @@ import ( | |||||
) | ||||||
|
||||||
const ( | ||||||
// QueryRegion is the region used for querying AWS before the user selects a region. | ||||||
QueryRegion = "us-east-1" | ||||||
|
||||||
selectAWSRegionPrompt = "Select the region you would like to deploy AWS resources to:" | ||||||
enterAWSIAMAcessKeyIDPrompt = "Enter the IAM access key id:" | ||||||
enterAWSIAMAcessKeyIDPlaceholder = "Enter IAM access key id..." | ||||||
enterAWSIAMSecretAccessKeyPrompt = "Enter your IAM Secret Access Key:" | ||||||
enterAWSIAMSecretAccessKeyPlaceholder = "Enter IAM secret access key..." | ||||||
errNotEmptyTemplate = "%s cannot be empty" | ||||||
confirmAWSAccountIDPromptFmt = "Use account id '%v'?" | ||||||
enterAWSAccountIDPrompt = "Enter the account ID:" | ||||||
enterAWSAccountIDPlaceholder = "Enter the account ID you want to use..." | ||||||
|
||||||
awsAccessKeysCreateInstructionFmt = "\nAWS IAM Access keys (Access key ID and Secret access key) are required to access and create AWS resources.\n\nFor example, you can create one using the following command:\n\033[36maws iam create-access-key\033[0m\n\nFor more information refer to https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html.\n\n" | ||||||
) | ||||||
|
@@ -53,12 +54,24 @@ func (r *Runner) enterAWSCloudProvider(ctx context.Context) (*aws.Provider, erro | |||||
return nil, err | ||||||
} | ||||||
|
||||||
accountId, err := r.getAccountId(ctx, accessKeyID, secretAccessKey) | ||||||
accountId, err := r.getAccountId(ctx) | ||||||
if err != nil { | ||||||
return nil, err | ||||||
} | ||||||
|
||||||
region, err := r.selectAWSRegion(ctx, QueryRegion, accessKeyID, secretAccessKey) | ||||||
// addAccountID, err := prompt.YesOrNoPrompt(fmt.Sprintf(confirmAWSAccountIDPromptFmt, accountId), prompt.ConfirmYes, r.Prompter) | ||||||
// if err != nil { | ||||||
// return nil, err | ||||||
// } | ||||||
|
||||||
// if !addAccountID { | ||||||
// accountId, err = r.Prompter.GetTextInput(enterAWSAccountIDPrompt, prompt.TextInputOptions{Placeholder: enterAWSAccountIDPlaceholder}) | ||||||
// if err != nil { | ||||||
// return nil, err | ||||||
// } | ||||||
// } | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this supposed to be uncommented? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missed to removed thess, updated in the pr |
||||||
|
||||||
region, err := r.selectAWSRegion(ctx) | ||||||
if err != nil { | ||||||
return nil, err | ||||||
} | ||||||
|
@@ -71,21 +84,36 @@ func (r *Runner) enterAWSCloudProvider(ctx context.Context) (*aws.Provider, erro | |||||
}, nil | ||||||
} | ||||||
|
||||||
func (r *Runner) getAccountId(ctx context.Context, accessKeyID, secretAccessKey string) (string, error) { | ||||||
callerIdentityOutput, err := r.awsClient.GetCallerIdentity(ctx, QueryRegion, accessKeyID, secretAccessKey) | ||||||
func (r *Runner) getAccountId(ctx context.Context) (string, error) { | ||||||
callerIdentityOutput, err := r.awsClient.GetCallerIdentity(ctx) | ||||||
if err != nil { | ||||||
return "", clierrors.MessageWithCause(err, "AWS credential verification failed.") | ||||||
return "", clierrors.MessageWithCause(err, "AWS Cloud Provider setup failed, please use aws configure to set up the configuration. More information :https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html") | ||||||
} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here, would it help user if we add some detail, like "AWS credential verification failed. Please use |
||||||
|
||||||
if callerIdentityOutput.Account == nil { | ||||||
return "", clierrors.MessageWithCause(err, "AWS credential verification failed: Account ID is nil.") | ||||||
} | ||||||
|
||||||
return *callerIdentityOutput.Account, nil | ||||||
accountID := *callerIdentityOutput.Account | ||||||
addAccountID, err := prompt.YesOrNoPrompt(fmt.Sprintf(confirmAWSAccountIDPromptFmt, accountID), prompt.ConfirmYes, r.Prompter) | ||||||
if err != nil { | ||||||
return "", err | ||||||
} | ||||||
|
||||||
if !addAccountID { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this be true so that the user can enter account id? Like the logic here is that if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we retrieve the account id using the local config , and in the yes or no prompt ask the user if they want to use the account id from local config, if user selects no then we propmpt to provide the account id. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can have a more meaningful name instead of |
||||||
accountID, err = r.Prompter.GetTextInput(enterAWSAccountIDPrompt, prompt.TextInputOptions{Placeholder: enterAWSAccountIDPlaceholder}) | ||||||
if err != nil { | ||||||
return "", err | ||||||
} | ||||||
} | ||||||
|
||||||
return accountID, nil | ||||||
} | ||||||
|
||||||
func (r *Runner) selectAWSRegion(ctx context.Context, region, accessKeyID, secretAccessKey string) (string, error) { | ||||||
listRegionsOutput, err := r.awsClient.ListRegions(ctx, region, accessKeyID, secretAccessKey) | ||||||
// selectAWSRegion prompts the user to select an AWS region from a list of available regions. | ||||||
// regions list is retrieved using the locally configured AWS account. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
func (r *Runner) selectAWSRegion(ctx context.Context) (string, error) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just for easier context, can you please add a comment here that it uses local aws config to list regions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added it |
||||||
listRegionsOutput, err := r.awsClient.ListRegions(ctx) | ||||||
if err != nil { | ||||||
return "", clierrors.MessageWithCause(err, "Listing AWS regions failed.") | ||||||
} | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should "default" be a const?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed the
config.WithSharedConfigProfile