GetAccountID returns the AWS account ID, caching the result
(ctx context.Context)
| 135 | |
| 136 | // GetAccountID returns the AWS account ID, caching the result |
| 137 | func (f *ClientFactory) GetAccountID(ctx context.Context) (string, error) { |
| 138 | f.mu.RLock() |
| 139 | if f.accountID != "" { |
| 140 | accountID := f.accountID |
| 141 | f.mu.RUnlock() |
| 142 | return accountID, nil |
| 143 | } |
| 144 | f.mu.RUnlock() |
| 145 | |
| 146 | f.mu.Lock() |
| 147 | defer f.mu.Unlock() |
| 148 | |
| 149 | // Double-check after acquiring write lock |
| 150 | if f.accountID != "" { |
| 151 | return f.accountID, nil |
| 152 | } |
| 153 | |
| 154 | stsClient := sts.New(f.session) |
| 155 | input := &sts.GetCallerIdentityInput{} |
| 156 | |
| 157 | result, err := stsClient.GetCallerIdentityWithContext(ctx, input) |
| 158 | if err != nil { |
| 159 | // Check for common AWS credential errors |
| 160 | if awsErr, ok := err.(awserr.Error); ok { |
| 161 | switch awsErr.Code() { |
| 162 | case "NoCredentialsErr": |
| 163 | return "", fmt.Errorf("AWS credentials not found. Please run 'aws configure' or set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables") |
| 164 | case "TokenRefreshRequired": |
| 165 | return "", fmt.Errorf("AWS credentials have expired. Please refresh your credentials or run 'aws sso login' if using SSO") |
| 166 | case "UnauthorizedOperation": |
| 167 | return "", fmt.Errorf("AWS credentials lack necessary permissions. Ensure your AWS user/role has CloudFormation, Lambda, and S3 permissions") |
| 168 | case "InvalidUserID.NotFound": |
| 169 | return "", fmt.Errorf("AWS credentials are invalid. Please check your AWS access key and secret key") |
| 170 | default: |
| 171 | return "", fmt.Errorf("AWS credential validation failed (%s): %v\n\n🔧 Troubleshooting:\n- Verify AWS credentials: aws sts get-caller-identity\n- Check region setting: %s", awsErr.Code(), awsErr.Message(), *f.session.Config.Region) |
| 172 | } |
| 173 | } |
| 174 | return "", fmt.Errorf("failed to validate AWS credentials: %w\n\n💡 Please check your AWS configuration", err) |
| 175 | } |
| 176 | |
| 177 | if result.Account == nil { |
| 178 | return "", fmt.Errorf("account ID not found in caller identity") |
| 179 | } |
| 180 | |
| 181 | f.accountID = *result.Account |
| 182 | return f.accountID, nil |
| 183 | } |
| 184 | |
| 185 | // ValidateCredentials checks if AWS credentials are valid |
| 186 | func (f *ClientFactory) ValidateCredentials(ctx context.Context) error { |
no test coverage detected