opensearch-project / opensearch-php

Official PHP Client for OpenSearch
Other
91 stars 54 forks source link

[BUG] PHP error "Exception: No alive nodes found in your cluster" #162

Open edgypet opened 11 months ago

edgypet commented 11 months ago

What is the bug?

I can connect to my OpenSearch instance through telnet, curl, and through the OpenSearch python SDK, but not PHP.

Here is the full error: Fatal error: Uncaught OpenSearch\Common\Exceptions\NoNodesAvailableException: No alive nodes found in your cluster in /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/ConnectionPool/StaticNoPingConnectionPool.php:67 Stack trace: #0 /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/Transport.php(85): OpenSearch\ConnectionPool\StaticNoPingConnectionPool->nextConnection() #1 /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/Transport.php(102): OpenSearch\Transport->getConnection() #2 /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/Connections/Connection.php(292): OpenSearch\Transport->performRequest() #3 /var/www/html/vendor/react/promise/src/FulfilledPromise.php(28): OpenSearch\Connections\Connection->OpenSearch\Connections\{closure}() #4 /var/www/html/vendor/ezimuel/ringphp/src/Future/CompletedFutureValue.php(65): React\Promise\FulfilledPromise->then() #5 /var/www/html/vendor/ezimuel/ringphp/src/Core.php(341): GuzzleHttp\Ring\Future\CompletedFutureValue->then() #6 /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/Connections/Connection.php(340): GuzzleHttp\Ring\Core::proxy() #7 /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/Connections/Connection.php(238): OpenSearch\Connections\Connection->OpenSearch\Connections\{closure}() #8 /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/Transport.php(113): OpenSearch\Connections\Connection->performRequest() #9 /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/Client.php(1392): OpenSearch\Transport->performRequest() #10 /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/Client.php(698): OpenSearch\Client->performRequest() #11 /var/www/html/opensearchtest.php(29): OpenSearch\Client->info() #12 /var/www/html/index.php(268): require('...') #13 {main} thrown in /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/ConnectionPool/StaticNoPingConnectionPool.php on line 67

How can one reproduce the bug?

Set-up EC2 instance on a VPC with a security group for open internal access. Create an OpenSearch cluster on same vpc, security group, and subnet with Fine-graned access control with a user/pass

Install composer version 2.2 of OpenSearch-php: "opensearch-project/opensearch-php": "^2.2",

Run simple php test script: `<?php

require dirname(FILE).'/vendor/autoload.php';

ini_set('display_errors', '1');

use OpenSearch\ClientBuilder;

$client = (new \OpenSearch\ClientBuilder()) ->setHosts(['https://vpc-[YOURINSTANCE].us-east-1.es.amazonaws.com:443']) ->setBasicAuthentication(OPENSEARCH_USER, OPENSEARCH_PASS) ->setSSLVerification(false) // For testing only. Use certificate for validation ->build();

var_dump($client->info());

die();

?> `

What is the expected behavior?

It should return information on my OpenSearch cluster

What is your host/environment?

php -v PHP 8.1.20 (cli) (built: Jun 14 2023 05:51:39) (NTS) Copyright (c) The PHP Group Zend Engine v4.1.20, Copyright (c) Zend Technologies with Zend OPcache v8.1.20, Copyright (c), by Zend Technologies

cat /etc/os-release PRETTY_NAME="Debian GNU/Linux 12 (bookworm)" NAME="Debian GNU/Linux" VERSION_ID="12" VERSION="12 (bookworm)" VERSION_CODENAME=bookworm ID=debian HOME_URL="https://www.debian.org/" SUPPORT_URL="https://www.debian.org/support" BUG_REPORT_URL="https://bugs.debian.org/"

Do you have any additional context?

I have tried the above on both ports 443 and 9200. Python OpenSearch SDK can connect on port 443.

shyim commented 11 months ago

Does it work with plain curl?

edgypet commented 11 months ago

@shyim No I am getting: "getaddrinfo() thread failed to start"

edgypet commented 11 months ago

After upgrading to Docker v24.0.4 and php v8.2-FPM, we can now curl to it and get string(12) "Unauthorized", but opensearch-php returns the same error from before.

shyim commented 11 months ago

can you show how do you connected with python sdk?

edgypet commented 11 months ago

Sure,

from opensearchpy import OpenSearch

host = 'vpc-[IDENTIFIER].us-east-1.es.amazonaws.com'
port = 443
auth = ('user', 'pass') # For testing only. Don't store credentials in code.
#ca_certs_path = '/full/path/to/root-ca.pem' # Provide a CA bundle if you use intermediate CAs with your root CA.

# Optional client certificates if you don't want to use HTTP basic authentication.
# client_cert_path = '/full/path/to/client.pem'
# client_key_path = '/full/path/to/client-key.pem'

# Create the client with SSL/TLS enabled, but hostname verification disabled.
client = OpenSearch(
    hosts = [{'host': host, 'port': port}],
    http_compress = True, # enables gzip compression for request bodies
    http_auth = auth,
    # client_cert = client_cert_path,
    # client_key = client_key_path,
    use_ssl = True,
    verify_certs = False,
    ssl_assert_hostname = False,
    ssl_show_warn = False,
    #ca_certs = ca_certs_path
)

# Create an index with non-default settings.
index_name = 'python-test-index-2'
index_body = {
  'settings': {
    'index': {
      'number_of_shards': 4
    }
  }
}

response = client.indices.create(index_name, body=index_body)
print('\nCreating index:')
print(response)

# Add a document to the index.
document = {
  'title': 'Moneyball',
  'director': 'Bennett Miller',
  'year': '2011'
}
id = '1'

response = client.index(
    index = index_name,
    body = document,
    id = id,
    refresh = True
)

print('\nAdding document:')
print(response)

# Search for the document.
q = 'miller'
query = {
  'size': 5,
  'query': {
    'multi_match': {
      'query': q,
      'fields': ['title^2', 'director']
    }
  }
}

response = client.search(
    body = query,
    index = index_name
)
print('\nSearch results:')
print(response)

# Delete the document.
response = client.delete(
    index = index_name,
    id = id
)

print('\nDeleting document:')
print(response)

# Delete the index.
response = client.indices.delete(
    index = index_name
)

print('\nDeleting index:')
print(response)
edgypet commented 11 months ago

After upgrading docker and php and curl is working well, I now get "UNAUTHORIZED" from opensearch with the same credentials that work for python.

Here is the code:

<?php

require_once 'common.php';

$no_template = true;

ini_set('display_errors', '1');

$host = 'https://vpc-[IDENTIFIER].us-east-1.es.amazonaws.com:443';
$username = OPENSEARCH_USER;
$password = OPENSEARCH_PASS;

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $host);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, $username . ':' . $password);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // For testing only. Use certificate for validation
curl_setopt($ch, CURLOPT_VERBOSE, true);

$response = curl_exec($ch);
$info = curl_getinfo($ch);
$error = curl_error($ch);

curl_close($ch);

echo '<pre>';
var_dump($response); // Raw response from OpenSearch
echo '</pre>';

use OpenSearch\ClientBuilder;

$client = (new \OpenSearch\ClientBuilder())
    ->setHosts(['https://vpc-[IDENTIFIER].us-east-1.es.amazonaws.com:443'])
    ->setBasicAuthentication(OPENSEARCH_USER, OPENSEARCH_PASS) // For testing only. Don't store credentials in code.
    ->setSSLVerification(false) // For testing only. Use certificate for validation
    ->build();

var_dump($client->info());

?>

Here is what that returns:

string(12) "Unauthorized"

Fatal error: Uncaught OpenSearch\Common\Exceptions\Unauthorized401Exception: Unauthorized in /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/Connections/Connection.php:652 Stack trace: #0 /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/Connections/Connection.php(328): OpenSearch\Connections\Connection->process4xxError() #1 /var/www/html/vendor/react/promise/src/FulfilledPromise.php(28): OpenSearch\Connections\Connection->OpenSearch\Connections\{closure}() #2 /var/www/html/vendor/ezimuel/ringphp/src/Future/CompletedFutureValue.php(65): React\Promise\FulfilledPromise->then() #3 /var/www/html/vendor/ezimuel/ringphp/src/Core.php(341): GuzzleHttp\Ring\Future\CompletedFutureValue->then() #4 /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/Connections/Connection.php(340): GuzzleHttp\Ring\Core::proxy() #5 /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/Connections/Connection.php(238): OpenSearch\Connections\Connection->OpenSearch\Connections\{closure}() #6 /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/Transport.php(113): OpenSearch\Connections\Connection->performRequest() #7 /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/Client.php(1392): OpenSearch\Transport->performRequest() #8 /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/Client.php(698): OpenSearch\Client->performRequest() #9 /var/www/html/opensearchtest.php(42): OpenSearch\Client->info() #10 /var/www/html/index.php(268): require('...') #11 {main} thrown in /var/www/html/vendor/opensearch-project/opensearch-php/src/OpenSearch/Connections/Connection.php on line 652
CSalih commented 11 months ago

@edgypet i've got the same unauthorized issue using AWS OpenSearch Service within a VPC but curl was connected successfully. In my case setting includePortInHostHeader = true in ClientBuilder::fromConfig solved the issue.

gerfigna commented 10 months ago

adding port in host url https://vpc-xxxxxx.amazonaws.com:443 solved the issue for me

saimedhi commented 1 month ago

Hello @edgypet, I hope you're doing well. Could you please confirm if this issue has been resolved? Thank you.