EcsCredentialProvider.php 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. <?php
  2. namespace Aws\Credentials;
  3. use Aws\Exception\CredentialsException;
  4. use GuzzleHttp\Promise;
  5. use GuzzleHttp\Psr7\Request;
  6. use GuzzleHttp\Promise\PromiseInterface;
  7. use Psr\Http\Message\ResponseInterface;
  8. /**
  9. * Credential provider that fetches credentials with GET request.
  10. * ECS environment variable is used in constructing request URI.
  11. */
  12. class EcsCredentialProvider
  13. {
  14. const SERVER_URI = 'http://169.254.170.2';
  15. const ENV_URI = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI";
  16. /** @var callable */
  17. private $client;
  18. /**
  19. * The constructor accepts following options:
  20. * - timeout: (optional) Connection timeout, in seconds, default 1.0
  21. * - client: An EcsClient to make request from
  22. *
  23. * @param array $config Configuration options
  24. */
  25. public function __construct(array $config = [])
  26. {
  27. $this->timeout = isset($config['timeout']) ? $config['timeout'] : 1.0;
  28. $this->client = isset($config['client'])
  29. ? $config['client']
  30. : \Aws\default_http_handler();
  31. }
  32. /**
  33. * Load ECS credentials
  34. *
  35. * @return PromiseInterface
  36. */
  37. public function __invoke()
  38. {
  39. $client = $this->client;
  40. $request = new Request('GET', self::getEcsUri());
  41. return $client(
  42. $request,
  43. ['timeout' => $this->timeout]
  44. )->then(function (ResponseInterface $response) {
  45. $result = $this->decodeResult((string) $response->getBody());
  46. return new Credentials(
  47. $result['AccessKeyId'],
  48. $result['SecretAccessKey'],
  49. $result['Token'],
  50. strtotime($result['Expiration'])
  51. );
  52. })->otherwise(function ($reason) {
  53. $reason = is_array($reason) ? $reason['exception'] : $reason;
  54. $msg = $reason->getMessage();
  55. throw new CredentialsException(
  56. "Error retrieving credential from ECS ($msg)"
  57. );
  58. });
  59. }
  60. /**
  61. * Fetch credential URI from ECS environment variable
  62. *
  63. * @return string Returns ECS URI
  64. */
  65. private function getEcsUri()
  66. {
  67. $creds_uri = getenv(self::ENV_URI);
  68. return self::SERVER_URI . $creds_uri;
  69. }
  70. private function decodeResult($response)
  71. {
  72. $result = json_decode($response, true);
  73. if (!isset($result['AccessKeyId'])) {
  74. throw new CredentialsException('Unexpected ECS credential value');
  75. }
  76. return $result;
  77. }
  78. }