opensearch-project / opensearch-php

Official PHP Client for OpenSearch
Other
110 stars 58 forks source link

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

Open edgypet opened 1 year ago

edgypet commented 1 year 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 1 year ago

Does it work with plain curl?

edgypet commented 1 year ago

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

edgypet commented 1 year 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 1 year ago

can you show how do you connected with python sdk?

edgypet commented 1 year 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 1 year 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 1 year 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 1 year ago

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

saimedhi commented 6 months ago

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