Skip to content

Commit

Permalink
fix: account_id resolution in ecs
Browse files Browse the repository at this point in the history
In order to support account id endpoint resolution on ECS when ECS does not return an AccountId field as part of its response.
What is being done in this change is trying to populate the AccountId field from the RoleArn returned in the response.
  • Loading branch information
yenfryherrerafeliz committed Jan 13, 2025
1 parent dcb43c0 commit e4733ea
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/Credentials/EcsCredentialProvider.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php
namespace Aws\Credentials;

use Aws\Arn\Arn;
use Aws\Exception\CredentialsException;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\GuzzleException;
Expand Down Expand Up @@ -86,6 +87,19 @@ public function __invoke()
]
)->then(function (ResponseInterface $response) {
$result = $this->decodeResult((string)$response->getBody());
if (!isset($result['AccountId']) && isset($result['RoleArn'])) {
try {
$parsedArn = new Arn($result['RoleArn']);
$result['AccountId'] = $parsedArn->getAccountId();
} catch (\Exception $e) {
// AccountId will be null
trigger_error(
"An error occured while parsing the ARN string: " . $e->getMessage(),
E_USER_WARNING
);
}
}

return new Credentials(
$result['AccessKeyId'],
$result['SecretAccessKey'],
Expand Down
34 changes: 34 additions & 0 deletions tests/Credentials/EcsCredentialProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,40 @@ public function testResolveCredentialsWithAccountId()

}

public function testResolveCredentialsWithAccountIdFromArn()
{
$testAccountId = 'foo';
$testArn = "arn:aws:iam::$testAccountId:role/role_name";
$expiration = time() + 1000;
$testHandler = function (RequestInterface $_) use ($expiration, $testArn) {
$jsonResponse = <<<EOF
{
"AccessKeyId": "foo",
"SecretAccessKey": "foo",
"Token": "bazz",
"Expiration": "@$expiration",
"RoleArn": "$testArn"
}
EOF;
return Promise\Create::promiseFor(new Response(200, [], $jsonResponse));
};
$provider = new EcsCredentialProvider([
'client' => $testHandler
]);
try {
/** @var Credentials $credentials */
$credentials = $provider()->wait();
$this->assertSame('foo', $credentials->getAccessKeyId());
$this->assertSame('foo', $credentials->getSecretKey());
$this->assertSame('bazz', $credentials->getSecurityToken());
$this->assertSame($expiration, $credentials->getExpiration());
$this->assertSame($testAccountId, $credentials->getAccountId());
} catch (GuzzleException $e) {
self::fail($e->getMessage());
}

}

/**
* @dataProvider successTestCases
*
Expand Down

0 comments on commit e4733ea

Please sign in to comment.