class EzThriftServerTestHarness(KazooTestCase): """The EzThriftServerTestHarness extends KazooTestCase to provide service discovery for clients in tests The thrift server is started using a TSimpleServer and registered with EzBake service discovery """ def setUp(self): super(EzThriftServerTestHarness, self).setUp() self.sd_client = ServiceDiscoveryClient(self.hosts) self.server_processes = [] @staticmethod def __thrift_server(processor, host="localhost", port=8449, use_simple_server=True, use_ssl=False, ca_certs=None, cert=None, key=None): if use_ssl: transport = TSSLServerSocket(host=host, port=port, ca_certs=ca_certs, cert=cert, key=key) else: transport = TSocket.TServerSocket(host=host, port=port) t_factory = TTransport.TBufferedTransportFactory() p_factory = TBinaryProtocol.TBinaryProtocolFactory() if use_simple_server: server = TServer.TSimpleServer(processor, transport, t_factory, p_factory) else: server = TServer.TThreadedServer(processor, transport, t_factory, p_factory) try: server.serve() print 'server started!' except (Exception, AttributeError, TTransportException) as e: print e logger.error("Server error: %s", e) def add_server(self, app_name, service_name, host, port, processor, use_simple_server=True, wait=1, use_ssl=False, ca_certs=None, cert=None, key=None): self.sd_client.register_endpoint(app_name, service_name, host, port) server_process = Process(target=self.__thrift_server, args=(processor, host, port, use_simple_server, use_ssl, ca_certs, cert, key)) server_process.start() time.sleep(wait) self.server_processes.append(server_process) def tearDown(self): super(EzThriftServerTestHarness, self).tearDown() for server_process in self.server_processes: if server_process.is_alive(): server_process.terminate()
def __init__(self, ez_props): if ez_props is None: raise Exception("Invalid EzProperties.") zk_con_str = ZookeeperConfiguration(ez_props).getZookeeperConnectionString() self.ezd_client = ServiceDiscoveryClient(zk_con_str) self.__applicationConfiguration = ApplicationConfiguration(ez_props) self.__applicationName = self.__applicationConfiguration.getApplicationName() self.__securityConfiguration = SecurityConfiguration(ez_props) self.__thriftConfiguration = ThriftConfiguration(ez_props) self.__rLock = threading.RLock() self.__serviceMap = {} self.__clientMap = {} self.__log = logging.getLogger(__name__) if self.__applicationName is None: self.__log.warn("No application name was found. Only common services will be discoverable.") else: self.__log.info("Application name: " + self.__applicationName) try: self.__common_services = list(self.ezd_client.get_common_services()) except Exception: self.__log.error("Unable to get common services") raise self.__refresh_end_points() self.__refresh_common_endpoints() thread = threading.Thread(target=self._evict_daemon) thread.setDaemon(True) thread.start()
def fetch_derived_token(self, ezSecurityToken, targetApp, excludedAuths=None, skipCache=False): """ Used when an application receives an EzSecurityToken as part of it's API but needs to call another service that itself takes an EzSecurityToken. :param ezSecurityToken: :param targetApp: :param excludedAuths: :return: """ # get the security id for target app (depending on if its a common # service or an application) dc = ServiceDiscoveryClient(self.zk_con_str) targetSecurityId = dc.get_security_id(targetApp) token_request = TokenRequest( self.appConfig.getSecurityID(), util.current_time_millis() ) token_request.tokenPrincipal = ezSecurityToken token_request.targetSecurityId = targetSecurityId token_request.excludeAuthorizations = excludedAuths # look in the cache (and return immediately if in cache) dn = ezSecurityToken.tokenPrincipal.principal request_chain = ezSecurityToken.tokenPrincipal.requestChain cache_key = self._get_cache_key(ezSecurityToken.type, dn, excludedAuths, request_chain, targetSecurityId) if not skipCache: token = self.__get_from_cache(cache_key) if token: return token # get token (since it wasn't found in the cache) headers = { HTTP_HEADER_USER_INFO: dn, HTTP_HEADER_SIGNATURE: self._sign(dn) } request, signature = self.build_request(headers, targetApp, exclude_authorizations=excludedAuths) return self._request_token_and_store(request, signature, "derived", dn, cache_key)
def clientServiceGreenlet(self): ezd = ServiceDiscoveryClient(gConfig.zk) ezd.register_endpoint(gConfig.appName, EzFrontendServiceName, gConfig.internal_hostname, gConfig.thriftPort) ezd.set_security_id_for_application(gConfig.appName, '_Ez_EFE') while gConfig.run: try: handler = ezRPKazookeeper.EzReverseProxyHandler( self._logger, self._sfh) processor = EzFrontendService.Processor(handler) transport = TSSLServerSocket( host=gConfig.internal_hostname, port=gConfig.thriftPort, verify_pattern=gConfig.ez_frontend_access, ca_certs=gConfig.ez_cafile, cert=gConfig.ez_certfile, key=gConfig.ez_keyfile) tfactory = TTransport.TBufferedTransportFactory() pfactory = TBinaryProtocol.TBinaryProtocolFactory() #server = TServer.TSimpleServer(processor,transport,tfactory,pfactory) server = TGeventServer(self._logger, processor, transport, tfactory, pfactory) gevent.sleep() server.serve() except Exception as e: self._logger.exception("Error in Thrift server: %s" % e) self._logger.info("exiting clientServiceGreenlet")
def clientServiceGreenlet(self): ezd = ServiceDiscoveryClient(gConfig.zk) ezd.register_endpoint(gConfig.appName, EzFrontendServiceName, gConfig.internal_hostname, gConfig.thriftPort) ezd.set_security_id_for_application(gConfig.appName, '_Ez_EFE') while gConfig.run: try: handler = ezRPKazookeeper.EzReverseProxyHandler(self._logger, self._sfh) processor = EzFrontendService.Processor(handler) transport = TSSLServerSocket(host=gConfig.internal_hostname, port=gConfig.thriftPort, ca_certs=gConfig.ez_cafile, cert=gConfig.ez_certfile, key=gConfig.ez_keyfile) tfactory = TTransport.TBufferedTransportFactory() pfactory = TBinaryProtocol.TBinaryProtocolFactory() #server = TServer.TSimpleServer(processor,transport,tfactory,pfactory) server = TGeventServer(self._logger, processor, transport, tfactory, pfactory) gevent.sleep() server.serve() except Exception as e: self._logger.exception("Error in Thrift server: %s" % e) self._logger.info("exiting clientServiceGreenlet")
def run(self): glt = ezRPGreenlet.EzReverseProxyGreenlet(self._logger, self._sfh) self._logger.info("starting greenlet for thrift service...") clientGreenlet = gevent.spawn(glt.clientServiceGreenlet) self._logger.info("started") self._logger.info("starting greenlet to monitor zookeeper...") kzGreenlet = gevent.spawn(glt.kzMonitorGreenlet) self._logger.info("started") self._logger.info( "starting greenlet to write out nginx configuration changes...") cfgProcessorGreenlet = gevent.spawn( glt.configurationChangeQueueGreenlet) self._logger.info("started") self._logger.info("starting greenlet to monitor for shutdown...") fd = gevent_inotifyx.init() wd = gevent_inotifyx.add_watch(fd, gConfig.shutdownFile, gevent_inotifyx.IN_DELETE) wGreenlet = gevent.spawn(glt.watchGreenlet, fd) self._logger.info("started") gConfig.addGreenlets(clientGreenlet, kzGreenlet, cfgProcessorGreenlet, wGreenlet) gevent.joinall([clientGreenlet]) self._logger.warn("joined thrift service greenlet") gevent.joinall([kzGreenlet]) self._logger.warn("joined zookeeper monitoring greenlet") gConfig.run = False while not gConfig.configurationChangeQueue.empty(): print "queue not empty" gConfig.configurationChangeQueue.get() print "got" gConfig.configurationChangeQueue.task_done() print "joining conf queue" gConfig.configurationChangeQueue.join() self._logger.warn("joined configuration queue") gevent.joinall([cfgProcessorGreenlet]) self._logger.warn("joined configuration change greenlet") gConfig.wGreenlet.join() self._logger.warn("joined shutdown monitor greenlet") ServiceDiscoveryClient(gConfig.zk).unregister_endpoint( gConfig.appName, EzFrontendServiceName, gConfig.internal_hostname, gConfig.thriftPort) self._logger.warn("unregistered from discovery service")
def setUp(self): """Replace the Zookeeper client on the module.""" super(ServiceDiscoveryClientTest, self).setUp() self.ezDiscovery = ServiceDiscoveryClient(self.hosts)
class ServiceDiscoveryClientTest(KazooTestCase): """Basic set of tests for ServiceDiscoveryClient.""" def setUp(self): """Replace the Zookeeper client on the module.""" super(ServiceDiscoveryClientTest, self).setUp() self.ezDiscovery = ServiceDiscoveryClient(self.hosts) def tearDown(self): """Clean up the Zookeeper entries.""" super(ServiceDiscoveryClientTest, self).tearDown() def test_register_endpoint(self): """Register an endpoint and make sure it ends up in Zookeeper.""" self.ezDiscovery.register_endpoint('foo', 'bar', 'localhost', 8080) endpoints = self.ezDiscovery.get_endpoints("foo", "bar") self.assertEqual(endpoints[0], "localhost:8080") def test_register_common_endpoint(self): """Register a common endpoint and make sure it ends up in Zookeeper.""" self.ezDiscovery.register_common_endpoint('bar', 'localhost', 8080) endpoints = self.ezDiscovery.get_common_endpoints("bar") self.assertEqual(endpoints[0], "localhost:8080") def test_unregister_endpoint(self): """Register and unregister an endpoint and make sure it is gone.""" self.ezDiscovery.register_endpoint('foo', 'bar', 'localhost', 8080) self.ezDiscovery.unregister_endpoint('foo', 'bar', 'localhost', 8080) endpoints = self.ezDiscovery.get_endpoints("foo", "bar") self.assertEqual(len(endpoints), 0) def test_unregister_common_endpoint(self): """Register and unregister a common endpoint and make sure it is gone. """ self.ezDiscovery.register_common_endpoint('bar', 'localhost', 8080) self.ezDiscovery.unregister_common_endpoint('bar', 'localhost', 8080) endpoints = self.ezDiscovery.get_common_endpoints("bar") self.assertEqual(len(endpoints), 0) def test_unregister_none_exist_endpoint(self): """ make sure no exception is raised """ self.ezDiscovery.unregister_endpoint('foo', 'bar', 'localhost', 8000) def test_unregister_multiple_endpoints(self): """Test that when multiple endpoints get made and some removed the tree of endpoints stays correct. """ self.ezDiscovery.register_endpoint('foo', 'bar', 'localhost', 8000) self.ezDiscovery.register_endpoint('foo', 'bar', 'localhost', 8888) # Unregister the first endpoint. self.ezDiscovery.unregister_endpoint('foo', 'bar', 'localhost', 8000) endpoints = self.ezDiscovery.get_endpoints('foo', 'bar') self.assertEqual(len(endpoints), 1) self.assertEqual(endpoints[0], 'localhost:8888') # Unregister the second endpoint. self.ezDiscovery.unregister_endpoint('foo', 'bar', 'localhost', 8888) endpoints = self.ezDiscovery.get_endpoints('foo', 'bar') self.assertEqual(len(endpoints), 0) base_path = '/'.join([ ServiceDiscoveryClient.NAMESPACE, 'foo', 'bar', ServiceDiscoveryClient.ENDPOINTS ]) self.assertTrue(self.client.exists(base_path)) def test_get_applications(self): """Test application list.""" # Create a few application endpoints. self.ezDiscovery.register_endpoint('foo', 'bar', 'localhost', 8000) self.ezDiscovery.register_endpoint('harry', 'sally', 'localhost', 8080) self.assertEqual(2, len(self.ezDiscovery.get_applications())) def test_get_services(self): """Test the application services list.""" # Create a few application endpoints. self.ezDiscovery.register_endpoint('foo', 'bar', 'localhost', 8000) self.ezDiscovery.register_endpoint('foo', 'baz', 'localhost', 8001) self.ezDiscovery.register_endpoint('harry', 'sally', 'localhost', 8080) # Make sure it returns the right count for a single service. self.assertEqual(2, len(self.ezDiscovery.get_services('foo'))) self.assertEqual(1, len(self.ezDiscovery.get_services('harry'))) self.assertEqual('sally', self.ezDiscovery.get_services('harry')[0]) def test_get_common_services(self): """Test fetching common services.""" # Make a few common services and and an external, ensure they return # properly. self.ezDiscovery.register_common_endpoint('foo', 'localhost', 8000) self.ezDiscovery.register_common_endpoint('bar', 'localhost', 8001) self.ezDiscovery.register_endpoint('harry', 'sally', 'localhost', 8080) self.assertEqual(2, len(self.ezDiscovery.get_common_services())) def test_get_endpoints(self): """Test endpoint list fetching.""" # Create a few application endpoints. self.ezDiscovery.register_endpoint('foo', 'bar', 'localhost', 8000) self.ezDiscovery.register_endpoint('foo', 'bar', 'localhost', 8001) self.ezDiscovery.register_endpoint('harry', 'sally', 'localhost', 8080) self.assertEqual(2, len(self.ezDiscovery.get_endpoints('foo', 'bar'))) def test_get_common_endpoints(self): """Test fetching common endpoints.""" # Create a few common endpoints and one not, test results. self.ezDiscovery.register_common_endpoint('foo', 'localhost', 8000) self.ezDiscovery.register_common_endpoint('foo', 'localhost', 8001) self.ezDiscovery.register_endpoint('harry', 'sally', 'localhost', 8080) self.assertEqual(2, len(self.ezDiscovery.get_common_endpoints('foo'))) self.assertEquals(0, len(self.ezDiscovery.get_common_endpoints('sally'))) def test_is_service_common(self): """Ensure only common services return true.""" # Test one that does not exist. self.assertFalse(self.ezDiscovery.is_service_common('foo')) self.ezDiscovery.register_common_endpoint('foo', 'localhost', 8000) self.assertTrue(self.ezDiscovery.is_service_common('foo')) self.ezDiscovery.register_endpoint('harry', 'sally', 'localhost', 8080) self.assertFalse(self.ezDiscovery.is_service_common('sally')) def test_set_security_id_for_application(self): """Ensure security id's get set for applications.""" self.ezDiscovery.register_endpoint('foo', 'bar', 'localhost', 8000) self.ezDiscovery.set_security_id_for_application('foo', 'sid') path = '/'.join([ ServiceDiscoveryClient.NAMESPACE, 'foo', ServiceDiscoveryClient.SECURITY, ServiceDiscoveryClient.SECURITY_ID ]) self.assertTrue(self.client.exists(path)) self.assertEquals('sid', self.client.get(path)[0]) def test_set_security_id_for_common_service(self): """Ensure security id's get set for common services.""" self.ezDiscovery.register_common_endpoint('foo', 'localhost', 8000) self.ezDiscovery.set_security_id_for_common_service('foo', 'sid') path = '/'.join([ ServiceDiscoveryClient.NAMESPACE, '/'.join([ServiceDiscoveryClient.COMMON_APP_NAME, 'foo']), ServiceDiscoveryClient.SECURITY, ServiceDiscoveryClient.SECURITY_ID ]) self.assertTrue(self.client.exists(path)) self.assertEquals('sid', self.client.get(path)[0]) def test_get_security_id_for_application(self): """Ensure fetching application security id's returns properly.""" # Fetch one that does not exist. self.assertEquals( None, self.ezDiscovery.get_security_id('foo') ) self.ezDiscovery.register_endpoint('foo', 'bar', 'localhost', 8000) self.ezDiscovery.set_security_id_for_application('foo', 'sid') self.assertEquals( 'sid', self.ezDiscovery.get_security_id('foo') ) def test_get_security_id_for_common_service(self): """Ensure fetching application security id's returns properly.""" # clear the cache self.ezDiscovery.securityIdCache.clear() # Fetch one does not exist. self.assertEquals( None, self.ezDiscovery.get_security_id('foo') ) self.ezDiscovery.register_common_endpoint('foo', 'localhost', 8000) self.ezDiscovery.set_security_id_for_common_service('foo', 'sid') self.assertEquals( 'sid', self.ezDiscovery.get_security_id('foo') )
def setUp(self): super(EzThriftServerTestHarness, self).setUp() self.sd_client = ServiceDiscoveryClient(self.hosts) self.server_processes = []
def setUp(self): """ """ super(ThriftClientPoolTest, self).setUp() ezd_client = ServiceDiscoveryClient(self.hosts) ez_props = EzConfiguration().getProperties() ez_props["thrift.use.ssl"] = "false" ez_props["zookeeper.connection.string"] = self.hosts application_name = ApplicationConfiguration(ez_props).getApplicationName() self.serverProcesses = [] for endpoint in ENDPOINTS: host, port = endpoint.split(':') port = int(port) server_process = Process(target=start_ezpz, args=(EzPzHandler(), port,)) server_process.start() time.sleep(1) self.serverProcesses.append(server_process) ezd_client.register_endpoint(application_name, "ezpz", host, port) ezd_client.register_endpoint(application_name, "service_one", 'localhost', 8083) ezd_client.register_endpoint(application_name, "service_two", 'localhost', 8084) ezd_client.register_endpoint(application_name, "service_three", 'localhost', 8085) ezd_client.register_common_endpoint('common_service_one', 'localhost', 8080) ezd_client.register_common_endpoint('common_service_two', 'localhost', 8081) ezd_client.register_common_endpoint('common_service_three', 'localhost', 8082) ezd_client.register_common_endpoint('common_service_multi', '192.168.1.1', 6060) ezd_client.register_common_endpoint('common_service_multi', '192.168.1.2', 6161) ezd_client.register_endpoint("NotThriftClientPool", "unknown_service_three", 'localhost', 8091) ezd_client.register_endpoint("NotThriftClientPool", "unknown_service_three", 'localhost', 8092) ezd_client.register_endpoint("NotThriftClientPool", "unknown_service_three", 'localhost', 8093) self.clientPool = ThriftClientPool(ez_props)
class ThriftClientPool(object): """ """ def __init__(self, ez_props): if ez_props is None: raise Exception("Invalid EzProperties.") zk_con_str = ZookeeperConfiguration(ez_props).getZookeeperConnectionString() self.ezd_client = ServiceDiscoveryClient(zk_con_str) self.__applicationConfiguration = ApplicationConfiguration(ez_props) self.__applicationName = self.__applicationConfiguration.getApplicationName() self.__securityConfiguration = SecurityConfiguration(ez_props) self.__thriftConfiguration = ThriftConfiguration(ez_props) self.__rLock = threading.RLock() self.__serviceMap = {} self.__clientMap = {} self.__log = logging.getLogger(__name__) if self.__applicationName is None: self.__log.warn("No application name was found. Only common services will be discoverable.") else: self.__log.info("Application name: " + self.__applicationName) try: self.__common_services = list(self.ezd_client.get_common_services()) except Exception: self.__log.error("Unable to get common services") raise self.__refresh_end_points() self.__refresh_common_endpoints() thread = threading.Thread(target=self._evict_daemon) thread.setDaemon(True) thread.start() def _evict_daemon(self): check_interval_millis = self.__thriftConfiguration.getMillisBetweenClientEvictionChecks() idle_threshold_millis = self.__thriftConfiguration.getMillisIdleBeforeEviction() while True: time.sleep(check_interval_millis * 0.001) with self.__rLock: for client in self.__clientMap.itervalues(): client._pool.evict_check(idle_threshold_millis) def _get_service_map(self): return self.__serviceMap def _get_client_map(self): return self.__clientMap def __refresh_end_points(self): if (self.__applicationName is not None) and (self.__applicationName != ''): try: for service in self.ezd_client.get_services(self.__applicationName): try: endpoints = self.ezd_client.get_endpoints(self.__applicationName, service) self._add_endpoints(service, endpoints) except Exception: self.__log.warn("No " + service + " for application " + self.__applicationName + " was found") except Exception: self.__log.warn( "Failed to get application services. " "This might be okay if the application hasn't registered any services." ) def __refresh_common_endpoints(self): try: for service in self.ezd_client.get_common_services(): try: endpoints = self.ezd_client.get_common_endpoints(service) self._add_endpoints(service, endpoints) except Exception: self.__log.warn("No common service " + service + " was found.") except Exception: self.__log.warn("Failed to get common services. This might be okay if no common service has been defined.") def _add_endpoints(self, service, endpoints): with self.__rLock: if service in self.__serviceMap: del self.__serviceMap[service] self.__serviceMap[service] = [] for endpoint in endpoints: self.__serviceMap[service].append(endpoint) @staticmethod def __get_thrift_connection_key(service_name, client_class): return service_name + "|" + str(client_class) def __get_endpoints(self, service_name, retry=True): with self.__rLock: if service_name in self.__serviceMap: return self.__serviceMap[service_name] if retry: self.__refresh_end_points() self.__refresh_common_endpoints() return self.__get_endpoints(service_name, retry=False) return None def get_client(self, app_name=None, service_name=None, clazz=None): if not service_name: raise ValueError("'service_name' does not have a valid value (%s)." % service_name) if not clazz: raise ValueError("'clazz' does not have a valid value (%s)." % clazz) try: key = self.__get_thrift_connection_key(service_name, clazz) with self.__rLock: if app_name: service = self.__applicationConfiguration.getApplicationServiceName(app_name, service_name) if service not in self.__serviceMap: endpoints = self.ezd_client.get_endpoints(app_name, service_name) self._add_endpoints(service, endpoints) # get client from client pool, or initialize client if key in self.__clientMap: client = self.__clientMap[key] else: endpoints = self.__get_endpoints(service_name) if endpoints is None: return None pool_size = self.__thriftConfiguration.getMaxIdleClients() if self.__thriftConfiguration.useSSL(): sc = self.__securityConfiguration ca_certs = sc.getTrustedSslCerts() key_file = sc.getPrivateKey() cert = sc.getSslCertificate() client = PoolingThriftClient(endpoints, clazz, pool_size=pool_size, use_ssl=True, ca_certs=ca_certs, cert=cert, key=key_file) else: client = PoolingThriftClient(endpoints, clazz, pool_size=pool_size) self.__clientMap[key] = client return client except Exception, e: raise TException(str(e))
def ca_server(ezconfig, service_name=None, ca_name="ezbakeca", zoo_host=None, host=None, port=None, verify_pattern=None, ssldir=None): Crypto.Random.atfork() # make sure zookeeper is available for registering with service discovery if zoo_host is None: zooConf = ZookeeperConfiguration(ezconfig) zoo_host = zooConf.getZookeeperConnectionString() if not zoo_host: raise RuntimeError("Zookeeper connection string must be specified " "in EzConfiguration") # make sure the ssl certificate directory is available if not ssldir: ac = ApplicationConfiguration(ezconfig) ssldir = ac.getCertificatesDir() if not ssldir: raise RuntimeError("Certificates Directory \"{0}\" must be set in" " EzConfiguration!".format( ApplicationConfiguration.CERTIFICATES_DIRECTORY_KEY)) # get a free port to bind to (and figure out our hostname) if not port: port = get_port(range(31005,34999)) if not host: host = socket.gethostname() # register with ezdiscovery ezdiscovery = ServiceDiscoveryClient(zoo_host) try: if service_name is None: service_name = ezbake.ezca.constants.SERVICE_NAME logger.info('Registering with service discovery') ezdiscovery.register_common_endpoint(service_name=service_name, host=host, port=port) ezdiscovery.set_security_id_for_common_service(service_name=service_name, security_id="EzCAService") except TimeoutError as e: logger.error("Fatal timeout connecting to zookeeper. Unable to " "register with service discovery.") raise e # create the thrift handler handler = EzCAHandler(ca_name, ezconfig) # generate/get the server SSL certs and write them to disk certs = handler._server_certs() cert_files = [] for k, cert in certs.items(): of = os.path.join(ssldir, k) cert_files.append(of) with os.fdopen(os.open(of, os.O_WRONLY | os.O_CREAT, 0o600), 'w') as ofs: ofs.write(str(cert)) # generate certs for configured clients (read from ezconfig) clients = ezconfig.get(EzCAHandler.CLIENT_CERTS) if clients: gen_client_certs(handler.ca, clients.split(','), ezconfig.get(EzCAHandler.CLIENT_CERT_O)) # start the thrift server processor = EzCA.Processor(handler) transport = TSSLServerSocket(host=host, port=port, verify_pattern=verify_pattern, ca_certs=cert_files[0], cert=cert_files[1], key=cert_files[2]) tfactory = TTransport.TBufferedTransportFactory() pfactory = TBinaryProtocol.TBinaryProtocolFactory() server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory) logger.info('Starting ezca service on {}:{}'.format(host,port)) server.serve()
def ca_server(ezconfig, service_name=None, ca_name="ezbakeca", zoo_host=None, host=None, port=None, verify_pattern=None, ssldir=None): Crypto.Random.atfork() # make sure zookeeper is available for registering with service discovery if zoo_host is None: zooConf = ZookeeperConfiguration(ezconfig) zoo_host = zooConf.getZookeeperConnectionString() if not zoo_host: raise RuntimeError("Zookeeper connection string must be specified " "in EzConfiguration") # make sure the ssl certificate directory is available if not ssldir: ac = ApplicationConfiguration(ezconfig) ssldir = ac.getCertificatesDir() if not ssldir: raise RuntimeError("Certificates Directory \"{0}\" must be set in" " EzConfiguration!".format( ApplicationConfiguration.CERTIFICATES_DIRECTORY_KEY)) # get a free port to bind to (and figure out our hostname) if not port: port = get_port(range(31005,34999)) if not host: host = socket.gethostname() # register with ezdiscovery ezdiscovery = ServiceDiscoveryClient(zoo_host) try: if service_name is None: service_name = ezbake.ezca.constants.SERVICE_NAME logger.info('Registering with service discovery') ezdiscovery.register_common_endpoint(service_name=service_name, host=host, port=port) except TimeoutError as e: logger.error("Fatal timeout connecting to zookeeper. Unable to " "register with service discovery.") raise e # create the thrift handler handler = EzCAHandler(ca_name, ezconfig) # generate/get the server SSL certs and write them to disk certs = handler._server_certs() cert_files = [] for k, cert in certs.items(): of = os.path.join(ssldir, k) cert_files.append(of) with os.fdopen(os.open(of, os.O_WRONLY | os.O_CREAT, 0o600), 'w') as ofs: ofs.write(str(cert)) # generate certs for configured clients (read from ezconfig) clients = ezconfig.get(EzCAHandler.CLIENT_CERTS) if clients: gen_client_certs(handler.ca, clients.split(','), ezconfig.get(EzCAHandler.CLIENT_CERT_O)) # start the thrift server processor = EzCA.Processor(handler) transport = TSSLServerSocket(host=host, port=port, verify_pattern=verify_pattern, ca_certs=cert_files[0], cert=cert_files[1], key=cert_files[2]) tfactory = TTransport.TBufferedTransportFactory() pfactory = TBinaryProtocol.TBinaryProtocolFactory() server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory) logger.info('Starting ezca service on {}:{}'.format(host,port)) server.serve()