etcd3gw: Discover API version automatically

etcd changed API version from v3beta to v3alpha, then v3, and because
of transition available api versions are different according to
the etcd server available.

This change implements the mechanism to detect the current api version
according to the etcd version obtained via the version API. So that
the url without api version works regardless of the etcd server used.

Closes-Bug: #2043810
Depends-on: https://review.opendev.org/c/openstack/etcd3gw/+/901244
Change-Id: Ib81390eb73feafe08d007db1ced4d0ceb3bde212
This commit is contained in:
Takashi Kajinami 2023-11-17 23:38:08 +09:00
parent 1aa447563a
commit f180411f42
4 changed files with 20 additions and 9 deletions

View File

@ -0,0 +1,11 @@
---
features:
- |
The ``etcd3gw`` driver now automatically discovers available etcd API
version and determines the api path. The driver detects the appropriate api
path before sending its first request, and the path is reused for its
subsequent requests. Services may need to be restarted after its backend
etcd server is upgraded, so that the new api path is detected.
The detection is skipped if the coordination backend url contains
the ``api_version`` query parameter or the ``ETCD3GW_API_PATH``
environment is set.

View File

@ -53,7 +53,7 @@ etcd3 =
grpcio>=1.18.0
protobuf<4.0 # BSD License (3 clause)
etcd3gw =
etcd3gw!=0.2.6,>=0.1.0 # Apache-2.0
etcd3gw!=0.2.6,>=2.3.0 # Apache-2.0
zake =
zake>=0.1.6 # Apache-2.0
redis =

View File

@ -181,7 +181,7 @@ class Etcd3Driver(coordination.CoordinationDriverCachedRunWatchers,
================== =======
Name Default
================== =======
api_version v3
api_version None
ca_cert None
cert_key None
cert_cert None
@ -200,9 +200,6 @@ class Etcd3Driver(coordination.CoordinationDriverCachedRunWatchers,
#: Default port used if none provided (4001 or 2379 are the common ones).
DEFAULT_PORT = 2379
#: Default api version if none provided
DEFAULT_API_VERSION = "v3"
GROUP_PREFIX = b"tooz/groups/"
def __init__(self, member_id, parsed_url, options):
@ -215,14 +212,18 @@ class Etcd3Driver(coordination.CoordinationDriverCachedRunWatchers,
cert_key = options.get('cert_key')
cert_cert = options.get('cert_cert')
timeout = int(options.get('timeout', self.DEFAULT_TIMEOUT))
api_version = options.get("api_version", self.DEFAULT_API_VERSION)
api_version = options.get("api_version")
if api_version:
api_path = "/" + api_version + "/"
else:
api_path = None
self.client = etcd3gw.client(host=host,
port=port,
protocol=protocol,
ca_cert=ca_cert,
cert_key=cert_key,
cert_cert=cert_cert,
api_path="/" + api_version + "/",
api_path=api_path,
timeout=timeout)
self.lock_timeout = int(options.get('lock_timeout', timeout))
self.membership_timeout = int(options.get(

View File

@ -34,8 +34,7 @@ class TestEtcd3Gw(testcase.TestCase):
'ca_cert': None,
'cert_key': None,
'cert_cert': None,
'api_path': (
"/" + etcd3gw_driver.Etcd3Driver.DEFAULT_API_VERSION + "/"),
'api_path': None,
'timeout': etcd3gw_driver.Etcd3Driver.DEFAULT_TIMEOUT},
{'coord_url': ('etcd3+https://my_host:666?ca_cert=/my/ca_cert&'
'cert_key=/my/cert_key&cert_cert=/my/cert_cert&'