| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- <?php
- namespace Aws\Credentials;
- use Aws\Exception\CredentialsException;
- use GuzzleHttp\Promise;
- use GuzzleHttp\Psr7\Request;
- use GuzzleHttp\Promise\PromiseInterface;
- use Psr\Http\Message\ResponseInterface;
- /**
- * Credential provider that provides credentials from the EC2 metadata server.
- */
- class InstanceProfileProvider
- {
- const SERVER_URI = 'http://169.254.169.254/latest/';
- const CRED_PATH = 'meta-data/iam/security-credentials/';
- /** @var string */
- private $profile;
- /** @var callable */
- private $client;
- /**
- * The constructor accepts the following options:
- *
- * - timeout: Connection timeout, in seconds.
- * - profile: Optional EC2 profile name, if known.
- *
- * @param array $config Configuration options.
- */
- public function __construct(array $config = [])
- {
- $this->timeout = isset($config['timeout']) ? $config['timeout'] : 1.0;
- $this->profile = isset($config['profile']) ? $config['profile'] : null;
- $this->client = isset($config['client'])
- ? $config['client'] // internal use only
- : \Aws\default_http_handler();
- }
- /**
- * Loads instance profile credentials.
- *
- * @return PromiseInterface
- */
- public function __invoke()
- {
- return Promise\coroutine(function () {
- if (!$this->profile) {
- $this->profile = (yield $this->request(self::CRED_PATH));
- }
- $json = (yield $this->request(self::CRED_PATH . $this->profile));
- $result = $this->decodeResult($json);
- yield new Credentials(
- $result['AccessKeyId'],
- $result['SecretAccessKey'],
- $result['Token'],
- strtotime($result['Expiration'])
- );
- });
- }
- /**
- * @param string $url
- * @return PromiseInterface Returns a promise that is fulfilled with the
- * body of the response as a string.
- */
- private function request($url)
- {
- $fn = $this->client;
- $request = new Request('GET', self::SERVER_URI . $url);
- return $fn($request, ['timeout' => $this->timeout])
- ->then(function (ResponseInterface $response) {
- return (string) $response->getBody();
- })->otherwise(function (array $reason) {
- $reason = $reason['exception'];
- $msg = $reason->getMessage();
- throw new CredentialsException(
- $this->createErrorMessage($msg, 0, $reason)
- );
- });
- }
- private function createErrorMessage($previous)
- {
- return "Error retrieving credentials from the instance profile "
- . "metadata server. ({$previous})";
- }
- private function decodeResult($response)
- {
- $result = json_decode($response, true);
- if ($result['Code'] !== 'Success') {
- throw new CredentialsException('Unexpected instance profile '
- . 'response code: ' . $result['Code']);
- }
- return $result;
- }
- }
|