openr/py/openr/clients/openr_client.py (103 lines of code) (raw):

#!/usr/bin/env python3 # Copyright (c) Meta Platforms, Inc. and affiliates. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import ssl from typing import Optional import bunch from openr.cli.utils.options import getDefaultOptions from openr.OpenrCtrl import OpenrCtrl from openr.thrift.OpenrCtrlCpp.clients import OpenrCtrlCpp as OpenrCtrlCppClient from openr.utils import consts from thrift.protocol import THeaderProtocol from thrift.py3.client import ClientType, get_client from thrift.py3.ssl import SSLContext, SSLVerifyOption from thrift.transport import THeaderTransport, TSocket, TSSLSocket class OpenrCtrlClient(OpenrCtrl.Client): """ Base class for secure and plain-text clients. Do not use this client directly. Instead use one of `OpenrCtrlPlainTextClient` or `OpenrCtrlSecureClient` """ def __init__(self, host: str, transport: THeaderTransport.THeaderTransport) -> None: self.host = host # Just for accessibility self._transport = transport self._transport.add_transform(THeaderTransport.TRANSFORM.ZSTD) OpenrCtrl.Client.__init__( self, THeaderProtocol.THeaderProtocol(self._transport) ) def __enter__(self): self._transport.open() return self def __exit__(self, type, value, traceback): self._transport.close() self._transport = None class OpenrCtrlPlainTextClient(OpenrCtrlClient): """ PlainText Thrift client for Open/R Prefer to use this for onbox communications or when secure thrift infrastructure is not setup/available """ def __init__( self, host: str, port: int = consts.Consts.CTRL_PORT, timeout_ms: int = 5000 ) -> None: socket = TSocket.TSocket(host=host, port=port) socket.setTimeout(timeout_ms) OpenrCtrlClient.__init__(self, host, THeaderTransport.THeaderTransport(socket)) class OpenrCtrlSecureClient(OpenrCtrlClient): """ Secure Thrift client for Open/R Prefer to use this for remote communications """ def __init__( self, host: str, cert_reqs: int, ca_file: str, cert_file: str, key_file: str, acceptable_peer_name: str, port: int = consts.Consts.CTRL_PORT, timeout_ms: int = 5000, ) -> None: verify_name = acceptable_peer_name if acceptable_peer_name != "" else None socket = TSSLSocket.TSSLSocket( host=host, port=port, cert_reqs=cert_reqs, ca_certs=ca_file, certfile=cert_file, keyfile=key_file, verify_name=verify_name, ) socket.setTimeout(timeout_ms) OpenrCtrlClient.__init__(self, host, THeaderTransport.THeaderTransport(socket)) def get_openr_ctrl_client( host: str, options: Optional[bunch.Bunch] = None ) -> OpenrCtrl.Client: """ Utility function to get openr clients with default smart options. For options override please look at openr.cli.utils.options.OPTIONS """ options = options if options else getDefaultOptions(host) if options.ssl: return OpenrCtrlSecureClient( host, options.cert_reqs, options.ca_file, options.cert_file, options.key_file, options.acceptable_peer_name, options.openr_ctrl_port, options.timeout, ) else: return OpenrCtrlPlainTextClient( options.host, options.openr_ctrl_port, options.timeout ) def get_openr_ctrl_cpp_client( host: str, options: Optional[bunch.Bunch] = None, client_type=ClientType.THRIFT_HEADER_CLIENT_TYPE, ) -> OpenrCtrlCppClient: """ Utility function to get py3 OpenrClient. We must eventually move all of our client use-case to py3 as python2 support is deprecated. https://fburl.com/ef0eq78f Major Usecase for: py3 supports streaming """ options = options if options else getDefaultOptions(host) ssl_context = None # Create ssl context if specified if options.ssl: # Translate ssl verification option ssl_verify_opt = SSLVerifyOption.NO_VERIFY if options.cert_reqs == ssl.CERT_OPTIONAL: ssl_verify_opt = SSLVerifyOption.VERIFY_REQ_CLIENT_CERT if options.cert_reqs == ssl.CERT_REQUIRED: ssl_verify_opt = SSLVerifyOption.VERIFY # Create ssl context ssl_context = SSLContext() ssl_context.set_verify_option(ssl_verify_opt) ssl_context.load_cert_chain( certfile=options.cert_file, keyfile=options.key_file ) ssl_context.load_verify_locations(cafile=options.ca_file) # Create and return client return get_client( OpenrCtrlCppClient, host=host, port=options.openr_ctrl_port, timeout=(options.timeout / 1000), # NOTE: Timeout expected is in seconds client_type=client_type, ssl_context=ssl_context, ssl_timeout=(options.timeout / 1000), # NOTE: Timeout expected is in seconds )