EcsCredentialProvider.php 2.6 KB

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