Skip to content

Commit 84d36b0

Browse files
committed
Enable to use Amazon Elasticsearch Service with IAM auth
1 parent fa01d30 commit 84d36b0

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
"illuminate/database": "~4.2|^5",
2222
"illuminate/config": "~4.2|^5",
2323
"nesbot/carbon": "~1.0",
24-
"elasticsearch/elasticsearch": ">1.0 <2.2"
24+
"elasticsearch/elasticsearch": ">1.0 <2.2",
25+
"aws/aws-sdk-php": "^3.18"
2526
},
2627
"require-dev": {
2728
"phpunit/phpunit": "~4.2|~5.0",

src/ElasticquentClientTrait.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
namespace Elasticquent;
44

5+
use GuzzleHttp\Psr7\Request;
6+
use Aws\Signature\SignatureV4;
7+
use Aws\Credentials\Credentials;
8+
use GuzzleHttp\Ring\Future\CompletedFutureArray;
9+
use GuzzleHttp\Psr7\Uri;
10+
use Psr\Http\Message\ResponseInterface;
11+
512
trait ElasticquentClientTrait
613
{
714

@@ -19,11 +26,72 @@ public function getElasticSearchClient()
1926

2027
// elasticsearch v2.0 using builder
2128
if (class_exists('\Elasticsearch\ClientBuilder')) {
29+
$awsConfig = $this->getElasticConfig('aws');
30+
if ( ! empty($awsConfig) && array_get($this->getElasticConfig('aws'), 'iam', false)) {
31+
if ($handler = $this->getAwsESHandler()) {
32+
array_set($config, 'handler', $handler);
33+
}
34+
}
35+
2236
return \Elasticsearch\ClientBuilder::fromConfig($config);
2337
}
2438

2539
// elasticsearch v1
2640
return new \Elasticsearch\Client($config);
2741
}
2842

43+
44+
/**
45+
* @return bool|\Closure
46+
*/
47+
private function getAwsESHandler()
48+
{
49+
$awsConfig = $this->getElasticConfig('aws');
50+
if (empty($awsConfig)) {
51+
return false;
52+
}
53+
54+
$key = array_get($awsConfig, 'key');
55+
$secret = array_get($awsConfig, 'secret');
56+
$region = array_get($awsConfig, 'region', 'us-west-2');
57+
58+
$psr7Handler = \Aws\default_http_handler();
59+
$signer = new SignatureV4('es', $region);
60+
61+
$handler = function (array $request) use (
62+
$psr7Handler,
63+
$signer,
64+
$key,
65+
$secret
66+
) {
67+
// Amazon ES listens on standard ports (443 for HTTPS, 80 for HTTP).
68+
$request['headers']['host'][0] = parse_url($request['headers']['host'][0], PHP_URL_HOST);
69+
70+
$credentials = new Credentials($key, $secret);
71+
72+
// Create a PSR-7 request from the array passed to the handler
73+
$psr7Request = new Request($request['http_method'],
74+
(new Uri($request['uri']))->withScheme($request['scheme'])->withHost($request['headers']['host'][0]),
75+
$request['headers'], $request['body']);
76+
77+
// Sign the PSR-7 request with credentials from the environment
78+
$signedRequest = $signer->signRequest($psr7Request, $credentials);
79+
80+
// Send the signed request to Amazon ES
81+
/** @var ResponseInterface $response */
82+
$response = $psr7Handler($signedRequest)->wait();
83+
84+
// Convert the PSR-7 response to a RingPHP response
85+
return new CompletedFutureArray([
86+
'status' => $response->getStatusCode(),
87+
'headers' => $response->getHeaders(),
88+
'body' => $response->getBody()->detach(),
89+
'transfer_stats' => ['total_time' => 0],
90+
'effective_url' => (string)$psr7Request->getUri(),
91+
]);
92+
};
93+
94+
return $handler;
95+
}
96+
2997
}

src/config/elasticquent.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,16 @@
2929

3030
'default_index' => 'my_custom_index_name',
3131

32+
/*
33+
|--------------------------------------------------------------------------
34+
| Enable to use Amazon Elasticsearch Service
35+
|--------------------------------------------------------------------------
36+
*/
37+
'aws' => [
38+
'iam' => true,
39+
'key' => 'YOUR_AWS_KEY',
40+
'secret' => 'YOUR_AWS_SECRET',
41+
'region' => 'us-west-2',
42+
]
43+
3244
];

0 commit comments

Comments
 (0)