I want to connect my Shopware 6.4 installation to an Elasticsearch instance. My Elasticsearch instance is secured by username and password.
I can not establish a connection between Shopware 6 and Elasticsearch, because i can not find a way to pass username and password to the configuration.
.env
SHOPWARE_ES_HOSTS="http://username:[email protected]:9201"
SHOPWARE_ES_ENABLED="1"
SHOPWARE_ES_INDEXING_ENABLED="1"
SHOPWARE_ES_INDEX_PREFIX="sw"
When running bin/console es:status
i get a 401 status code.
Unknown 401 error from Elasticsearch null
When i try to connect via curl to my Elasticsearch instance, i can connect without a problem:
curl -u 'user:password' http://elasticsearch.local:9201
{
"name" : "elasticsearch",
"cluster_name" : "es-cluster-01",
"cluster_uuid" : "dRsu0d_PQKyTI5RDe_r79Q",
"version" : {
"number" : "7.14.1",
"build_flavor" : "default",
"build_type" : "deb",
"build_hash" : "66b55ebfa59c92c15db3f69a335d500018b3331e",
"build_date" : "2021-08-26T09:01:05.390870785Z",
"build_snapshot" : false,
"lucene_version" : "8.9.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
How can i pass username and password in Shopware to connect to my Elasticsearch instance?
CodePudding user response:
The config is passed via
config/services/defaults.xml:12
to the client:
<service id="Elasticsearch\Client" public="true">
<factory class="Shopware\Elasticsearch\Framework\ClientFactory" method="createClient" />
<argument>%elasticsearch.hosts%</argument>
<argument type="service" id="shopware.elasticsearch.logger" />
<argument>%kernel.debug%</argument>
</service>
The hosts as passed to the clientbuilder:
\Shopware\Elasticsearch\Framework\ClientFactory::createClient
According to
Specify elasticsearch username/password with Elasticsearch-PHP ClientBuilder
it use possible to have a user and pass there.
There is:
vendor/elasticsearch/elasticsearch/src/Elasticsearch/ClientBuilder.php:676
$host = $this->extractURIParts($host);
And:
/**
* @throws InvalidArgumentException
*/
private function extractURIParts(string $host): array
{
$parts = parse_url($host);
if ($parts === false) {
throw new InvalidArgumentException(sprintf('Could not parse URI: "%s"', $host));
}
if (isset($parts['port']) !== true) {
$parts['port'] = 9200;
}
return $parts;
}
This is just a parse_url
call which should extract user and pass.
Long story short: You approach actually should work.
For further debugging I suggest to xdebug into
\Elasticsearch\ClientBuilder::extractURIParts
or put some temporary debug code:
private function extractURIParts(string $host): array
{
$parts = parse_url($host);
var_dump($parts); die();
Does you username or password maybe have some special characters which might cause problems?
Update - Solution found
The problem was a special character in the password. Special characters like $
need to be escaped in the .env
file.
If the password is 123$123
then the correct string would be:
SHOPWARE_ES_HOSTS="http://username:123\[email protected]:9201"
So the $
needs to be escaped by a backslash (\
).