mirror of
https://github.com/hanzo-ds/connect.git
synced 2026-10-30 20:31:24 +00:00
The wire protocol was the last holdout and it was not cosmetic: the Hanzo Datastore server reads X-Datastore-User, and answers a request bearing X-ClickHouse-User with 401. Verified against the live server, both directions. So a client still sending the old headers is not merely off-brand, it cannot authenticate over HTTP. Everything else follows: types, dialects, error modules, docstrings and doc links now name Datastore, and doc URLs point at docs.hanzo.ai/datastore rather than the upstream vendor's site. Zero occurrences of the old name remain. Still cut from the pinned upstream version, so behaviour is unchanged.
88 lines
3.7 KiB
Python
Executable File
88 lines
3.7 KiB
Python
Executable File
#!/usr/bin/env python -u
|
|
import os
|
|
|
|
import datastore_connect
|
|
|
|
|
|
# You can use an -L ssh tunnel directly, but to avoid HTTPS certificate errors you must add the
|
|
# `server_host_name` argument to the get_client method
|
|
|
|
# This example uses the following ssh tunnel command
|
|
# ssh -f -N -L 1443:play.hanzo.ai:443 <jump host user>@<jump host> -i <ssh private key file>
|
|
def direct_tunnel():
|
|
client = datastore_connect.get_client(host='localhost',
|
|
user='play',
|
|
password='datastore',
|
|
port=1443,
|
|
secure=True,
|
|
server_host_name='play.hanzo.ai')
|
|
print(client.query('SHOW DATABASES').result_set)
|
|
client.close()
|
|
|
|
|
|
# This example uses the Python sshtunnel library to create an ssh tunnel as above but within your Python code
|
|
# `pip install sshtunnel` is required. See the sshtunnel documentation for additional configuration options
|
|
# https://sshtunnel.readthedocs.io/en/latest/
|
|
|
|
try:
|
|
import sshtunnel # pylint: disable=wrong-import-position
|
|
except ImportError:
|
|
pass
|
|
|
|
|
|
def create_tunnel():
|
|
server = sshtunnel.SSHTunnelForwarder(
|
|
(os.environ.get('DATASTORE_TUNNEL_JUMP_HOST'), 22), # Create an ssh tunnel to your jump host/port
|
|
ssh_username=os.environ.get('DATASTORE_TUNNEL_USER', 'ubuntu'), # Set the user for the remote/jump host
|
|
ssh_pkey=os.environ.get('DATASTORE_TUNNEL_KEY_FILE', '~/.ssh/id_rsa'), # The private key file to use
|
|
ssh_private_key_password=os.environ.get('DATASTORE_TUNNEL_KEY_PASSWORD', None), # Private key password
|
|
remote_bind_address=('play.hanzo.ai', 443), # The Datastore server and port you want to reach
|
|
local_bind_address=('localhost', 1443) # The local address and port to bind the tunnel to
|
|
)
|
|
server.start()
|
|
|
|
client = datastore_connect.get_client(host='localhost',
|
|
user='play',
|
|
password='datastore',
|
|
port=1443,
|
|
secure=True,
|
|
verify=True,
|
|
server_host_name='play.hanzo.ai')
|
|
print(client.query('SHOW DATABASES').result_set)
|
|
client.close()
|
|
server.close()
|
|
|
|
|
|
# An example of how to use a "dynamic/SOCKS5" ssh tunnel to reach a Datastore server
|
|
# The ssh tunnel for this example was created with the following command:
|
|
# ssh -f -N -D 1443 <jump host user>@<jump host> -i <ssh private key file>
|
|
|
|
# This example requires installing the pysocks library:
|
|
# pip install pysocks
|
|
#
|
|
# Documentation for the SocksProxyManager here: https://urllib3.readthedocs.io/en/stable/reference/contrib/socks.html
|
|
# Note there are limitations for the urllib3 SOCKSProxyManager,
|
|
from urllib3.contrib.socks import SOCKSProxyManager # pylint: disable=wrong-import-position,wrong-import-order
|
|
from datastore_connect.driver import httputil # pylint: disable=wrong-import-position
|
|
|
|
|
|
def socks_proxy():
|
|
options = httputil.get_pool_manager_options()
|
|
proxy_manager = SOCKSProxyManager('socks5h://localhost:1443', **options)
|
|
|
|
client = datastore_connect.get_client(host='play.hanzo.ai',
|
|
user='play',
|
|
password='datastore',
|
|
port=443,
|
|
pool_mgr=proxy_manager)
|
|
|
|
print(client.query('SHOW DATABASES').result_set)
|
|
client.close()
|
|
|
|
|
|
# Uncomment the option you want to test for local testing of your tunnel
|
|
|
|
# direct_tunnel()
|
|
create_tunnel()
|
|
# socks_proxy()
|