Skip to content

Add support for using cloud_id when instantiating conections #957

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Changelog
=========
7.1.0 (dev)
-----------
* Add connection parameter for Elastic Cloud cloud_id.

7.0.1 (2019-05019)
-----------
Expand Down
15 changes: 11 additions & 4 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,22 @@ Simple use-case::

# create an index in elasticsearch, ignore status code 400 (index already exists)
>>> es.indices.create(index='my-index', ignore=400)
{u'acknowledged': True}
{'acknowledged': True, 'shards_acknowledged': True, 'index': 'my-index'}

# datetimes will be serialized
>>> es.index(index="my-index", id=42, body={"any": "data", "timestamp": datetime.now()})
{u'_id': u'42', u'_index': u'my-index', u'_type': u'test-type', u'_version': 1, u'ok': True}
{'_index': 'my-index',
'_type': '_doc',
'_id': '42',
'_version': 1,
'result': 'created',
'_shards': {'total': 2, 'successful': 1, 'failed': 0},
'_seq_no': 0,
'_primary_term': 1}

# but not deserialized
>>> es.get(index="my-index", id=42)['_source']
{u'any': u'data', u'timestamp': u'2013-05-12T19:45:31.804229'}
{'any': 'data', 'timestamp': '2019-05-17T17:28:10.329598'}

`Full documentation`_.

Expand All @@ -97,7 +104,7 @@ Simple use-case::
Elastic Cloud (and SSL) use-case::

>>> from elasticsearch import Elasticsearch
>>> es = Elasticsearch("https://elasticsearch.url:port", http_auth=('elastic','yourpassword'))
>>> es = Elasticsearch(cloud_id="<some_long_cloud_id>", http_auth=('elastic','yourpassword'))
>>> es.info()

Using SSL Context with a self-signed cert use-case::
Expand Down
12 changes: 12 additions & 0 deletions elasticsearch/connection/http_requests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import time
import warnings
from base64 import decodestring

try:
import requests
Expand Down Expand Up @@ -34,6 +35,8 @@ class RequestsHttpConnection(Connection):
:arg client_key: path to the file containing the private key if using
separate cert and key files (client_cert will contain only the cert)
:arg headers: any custom http headers to be add to requests
:arg cloud_id: The Cloud ID from ElasticCloud. Convient way to connect to cloud instances.
Other host connection params will be ignored.
"""

def __init__(
Expand All @@ -48,12 +51,21 @@ def __init__(
client_cert=None,
client_key=None,
headers=None,
cloud_id=None,
**kwargs
):
if not REQUESTS_AVAILABLE:
raise ImproperlyConfigured(
"Please install requests to use RequestsHttpConnection."
)
if cloud_id:
cluster_name, cloud_id = cloud_id.split(":")
url, es_uuid, kibana_uuid = (
decodestring(cloud_id.encode("utf-8")).decode("utf-8").split("$")
)
host = "%s.%s" % (es_uuid, url)
port = 9243
use_ssl = True

super(RequestsHttpConnection, self).__init__(
host=host, port=port, use_ssl=use_ssl, **kwargs
Expand Down
12 changes: 12 additions & 0 deletions elasticsearch/connection/http_urllib3.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from urllib3.util.retry import Retry
import warnings
import gzip
from base64 import decodestring

# sentinal value for `verify_certs`.
# This is used to detect if a user is passing in a value for `verify_certs`
Expand Down Expand Up @@ -72,6 +73,8 @@ class Urllib3HttpConnection(Connection):
information.
:arg headers: any custom http headers to be add to requests
:arg http_compress: Use gzip compression
:arg cloud_id: The Cloud ID from ElasticCloud. Convient way to connect to cloud instances.
Other host connection params will be ignored.
"""

def __init__(
Expand All @@ -92,9 +95,18 @@ def __init__(
headers=None,
ssl_context=None,
http_compress=False,
cloud_id=None,
**kwargs
):

if cloud_id:
cluster_name, cloud_id = cloud_id.split(":")
url, es_uuid, kibana_uuid = (
decodestring(cloud_id.encode("utf-8")).decode("utf-8").split("$")
)
host = "%s.%s" % (es_uuid, url)
port = "9243"
use_ssl = True
super(Urllib3HttpConnection, self).__init__(
host=host, port=port, use_ssl=use_ssl, **kwargs
)
Expand Down
18 changes: 18 additions & 0 deletions test_elasticsearch/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ def test_ssl_context(self):
self.assertIsInstance(con.pool.conn_kw["ssl_context"], ssl.SSLContext)
self.assertTrue(con.use_ssl)

def test_http_cloud_id(self):
con = Urllib3HttpConnection(
cloud_id="foobar:ZXhhbXBsZS5jbG91ZC5jb20kMGZkNTBmNjIzMjBlZDY1MzlmNmNiNDhlMWI2OCRhYzUzOTVhODgz\nNDU2NmM5ZjE1Y2Q4ZTQ5MGE=\n"
)
self.assertTrue(con.use_ssl)
self.assertEquals(
con.host, "https://0fd50f62320ed6539f6cb48e1b68.example.cloud.com:9243"
)

def test_http_compression(self):
con = Urllib3HttpConnection(http_compress=True)
self.assertTrue(con.http_compress)
Expand Down Expand Up @@ -151,6 +160,15 @@ def test_timeout_set(self):
con = RequestsHttpConnection(timeout=42)
self.assertEquals(42, con.timeout)

def test_http_cloud_id(self):
con = RequestsHttpConnection(
cloud_id="foobar:ZXhhbXBsZS5jbG91ZC5jb20kMGZkNTBmNjIzMjBlZDY1MzlmNmNiNDhlMWI2OCRhYzUzOTVhODgz\nNDU2NmM5ZjE1Y2Q4ZTQ5MGE=\n"
)
self.assertTrue(con.use_ssl)
self.assertEquals(
con.host, "https://0fd50f62320ed6539f6cb48e1b68.example.cloud.com:9243"
)

def test_uses_https_if_verify_certs_is_off(self):
with warnings.catch_warnings(record=True) as w:
con = self._get_mock_connection(
Expand Down