@@ -142,99 +142,43 @@ def __call__(self, context, callback):
142142 callback (metadata , None )
143143
144144
145- class Etcd3Client (object ):
145+ class MultiEndpointEtcd3Client (object ):
146146 """
147- etcd v3 API client.
148-
149- If ``endpoints`` is specified, ``host``, ``port``, ``ca_cert``,
150- ``cert_key``, ``cert_cert``, and ``grpc_options`` must not be.
147+ etcd v3 API client with multiple endpoints.
151148
152149 When failover is enabled, requests still will not be auto-retried.
153150 Instead, the application may retry the request, and the ``Etcd3Client``
154151 will then attempt to send it to a different endpoint that has not recently
155152 failed. If all configured endpoints have failed and are not ready to be
156153 retried, an ``exceptions.NoServerAvailableError`` will be raised.
157154
158- :param host: Host to connect to, 'localhost' if not specified
159- :type host: str, optional
160- :param port: Port to connect to on host, 2379 if not specified
161- :type port: int, optional
162155 :param endpoints: Endpoints to use in lieu of host and port
163156 :type endpoints: Iterable(Endpoint), optional
164- :param ca_cert: Filesystem path of etcd CA certificate
165- :type ca_cert: str or os.PathLike, optional
166- :param cert_key: Filesystem path of client key
167- :type cert_key: str or os.PathLike, optional
168- :param cert_cert: Filesystem path of client certificate
169- :type cert_cert: str or os.PathLike, optional
170157 :param timeout: Timeout for all RPC in seconds
171158 :type timeout: int or float, optional
172159 :param user: Username for authentication
173160 :type user: str, optional
174161 :param password: Password for authentication
175162 :type password: str, optional
176- :param dict grpc_options: Additional gRPC options
177- :type grpc_options: dict, optional
178163 :param bool failover: Failover between endpoints, default False
179164 """
180165
181- def __init__ (self , host = None , port = None , endpoints = None ,
182- ca_cert = None , cert_key = None , cert_cert = None , timeout = None ,
183- user = None , password = None , grpc_options = None , failover = False ):
184-
185- if endpoints and any (
186- (host , port , ca_cert , cert_key , cert_cert , grpc_options )
187- ):
188- raise ValueError (
189- "endpoints may not be specified with host, port, ca_cert, "
190- "cert_key, cert_cert, or grpc_options"
191- )
192- host = host or "localhost"
193- port = port or 2379
166+ def __init__ (self , endpoints = None , timeout = None , user = None , password = None ,
167+ failover = False ):
194168
195169 self .metadata = None
196170 self .failover = failover
197171
198172 # Cache GRPC stubs here
199173 self ._stubs = {}
200174
201- # Step 1: verify credentials
202- cert_params = [c is not None for c in (cert_cert , cert_key )]
203- if ca_cert is not None :
204- if all (cert_params ):
205- credentials = self .get_secure_creds (
206- ca_cert ,
207- cert_key ,
208- cert_cert
209- )
210- self .uses_secure_channel = True
211- elif any (cert_params ):
212- # some of the cert parameters are set
213- raise ValueError (
214- 'to use a secure channel ca_cert is required by itself, '
215- 'or cert_cert and cert_key must both be specified.' )
216- else :
217- credentials = self .get_secure_creds (ca_cert , None , None )
218- self .uses_secure_channel = True
219- else :
220- self .uses_secure_channel = False
221- credentials = None
222-
223- # Step 2: if more than one endpoint is available, add all of them, else
224- # use the host/port combination
225- if endpoints is None :
226- ep = Endpoint (host , port , secure = self .uses_secure_channel ,
227- creds = credentials , opts = grpc_options )
228- self .endpoints = {ep .netloc : ep }
229- else :
230- # If the endpoints are passed externally, just use those.
231- self .endpoints = {ep .netloc : ep for ep in endpoints }
232-
175+ # Step 1: setup endpoints
176+ self .endpoints = {ep .netloc : ep for ep in endpoints }
233177 self ._current_endpoint_label = random .choice (
234178 list (self .endpoints .keys ())
235179 )
236180
237- # Step 3 : if auth is enabled, call the auth endpoint
181+ # Step 2 : if auth is enabled, call the auth endpoint
238182 self .timeout = timeout
239183 self .call_credentials = None
240184 cred_params = [c is not None for c in (user , password )]
@@ -1393,18 +1337,74 @@ def snapshot(self, file_obj):
13931337 file_obj .write (response .blob )
13941338
13951339
1396- def client (host = None , port = None , endpoints = None ,
1340+ class Etcd3Client (MultiEndpointEtcd3Client ):
1341+ """
1342+ etcd v3 API client.
1343+
1344+ :param host: Host to connect to, 'localhost' if not specified
1345+ :type host: str, optional
1346+ :param port: Port to connect to on host, 2379 if not specified
1347+ :type port: int, optional
1348+ :param ca_cert: Filesystem path of etcd CA certificate
1349+ :type ca_cert: str or os.PathLike, optional
1350+ :param cert_key: Filesystem path of client key
1351+ :type cert_key: str or os.PathLike, optional
1352+ :param cert_cert: Filesystem path of client certificate
1353+ :type cert_cert: str or os.PathLike, optional
1354+ :param timeout: Timeout for all RPC in seconds
1355+ :type timeout: int or float, optional
1356+ :param user: Username for authentication
1357+ :type user: str, optional
1358+ :param password: Password for authentication
1359+ :type password: str, optional
1360+ :param dict grpc_options: Additional gRPC options
1361+ :type grpc_options: dict, optional
1362+ """
1363+
1364+ def __init__ (self , host = 'localhost' , port = 2379 , ca_cert = None ,
1365+ cert_key = None , cert_cert = None , timeout = None , user = None ,
1366+ password = None , grpc_options = None ):
1367+
1368+ # Step 1: verify credentials
1369+ cert_params = [c is not None for c in (cert_cert , cert_key )]
1370+ if ca_cert is not None :
1371+ if all (cert_params ):
1372+ credentials = self .get_secure_creds (
1373+ ca_cert ,
1374+ cert_key ,
1375+ cert_cert
1376+ )
1377+ self .uses_secure_channel = True
1378+ elif any (cert_params ):
1379+ # some of the cert parameters are set
1380+ raise ValueError (
1381+ 'to use a secure channel ca_cert is required by itself, '
1382+ 'or cert_cert and cert_key must both be specified.' )
1383+ else :
1384+ credentials = self .get_secure_creds (ca_cert , None , None )
1385+ self .uses_secure_channel = True
1386+ else :
1387+ self .uses_secure_channel = False
1388+ credentials = None
1389+
1390+ # Step 2: create Endpoint
1391+ ep = Endpoint (host , port , secure = self .uses_secure_channel ,
1392+ creds = credentials , opts = grpc_options )
1393+
1394+ super (Etcd3Client , self ).__init__ (endpoints = [ep ], timeout = timeout ,
1395+ user = user , password = password )
1396+
1397+
1398+ def client (host = 'localhost' , port = 2379 ,
13971399 ca_cert = None , cert_key = None , cert_cert = None , timeout = None ,
1398- user = None , password = None , grpc_options = None , failover = False ):
1400+ user = None , password = None , grpc_options = None ):
13991401 """Return an instance of an Etcd3Client."""
14001402 return Etcd3Client (host = host ,
14011403 port = port ,
1402- endpoints = endpoints ,
14031404 ca_cert = ca_cert ,
14041405 cert_key = cert_key ,
14051406 cert_cert = cert_cert ,
14061407 timeout = timeout ,
14071408 user = user ,
14081409 password = password ,
1409- grpc_options = grpc_options ,
1410- failover = failover )
1410+ grpc_options = grpc_options )
0 commit comments