Merge pull request #55 from guewen/swift-auth-session

attachment_swift: share a session for all connections
This commit is contained in:
Guewen Baconnier
2019-05-07 15:29:16 +02:00
committed by GitHub
co-authored by GitHub
4 changed files with 69 additions and 11 deletions
-1
View File
@@ -13,7 +13,6 @@ addons:
- python-lxml # because pip installation is slow - python-lxml # because pip installation is slow
- python-simplejson - python-simplejson
- python-serial - python-serial
- python-yaml
python: python:
- '2.7' - '2.7'
+2
View File
@@ -16,6 +16,7 @@ Configure accesses with environment variables:
* ``SWIFT_TENANT_NAME`` * ``SWIFT_TENANT_NAME``
* ``SWIFT_ACCOUNT`` * ``SWIFT_ACCOUNT``
* ``SWIFT_PASSWORD`` * ``SWIFT_PASSWORD``
* ``SWIFT_REGION_NAME`` : optional region
* ``SWIFT_WRITE_CONTAINER`` : Name of the container to use in the store (created if not existing) * ``SWIFT_WRITE_CONTAINER`` : Name of the container to use in the store (created if not existing)
Read-only mode: Read-only mode:
@@ -44,6 +45,7 @@ The python-swiftclient can be used from the command line, useful to test:
export OS_USERNAME={SWIFT_ACCOUNT} export OS_USERNAME={SWIFT_ACCOUNT}
export OS_PASSWORD={SWIFT_PASSWORD} export OS_PASSWORD={SWIFT_PASSWORD}
export OS_TENANT_NAME={SWIFT_TENANT_NAME} export OS_TENANT_NAME={SWIFT_TENANT_NAME}
export SWIFT_REGION_NAME={SWIFT_REGION_NAME}
export OS_AUTH_URL=https://auth.cloud.ovh.net/v2.0 export OS_AUTH_URL=https://auth.cloud.ovh.net/v2.0
swift stat swift stat
+62 -8
View File
@@ -14,6 +14,9 @@ _logger = logging.getLogger(__name__)
try: try:
import swiftclient import swiftclient
import keystoneauth1
import keystoneauth1.identity
import keystoneauth1.session
from swiftclient.exceptions import ClientException from swiftclient.exceptions import ClientException
except ImportError: except ImportError:
swiftclient = None swiftclient = None
@@ -21,6 +24,54 @@ except ImportError:
_logger.debug("Cannot 'import swiftclient'.") _logger.debug("Cannot 'import swiftclient'.")
SWIFT_TIMEOUT = 15
class SwiftSessionStore(object):
"""Keep in memory the current Swift Auth session
The auth endpoint has a rate limit on swift, if every operation
on the filestore authenticate, the limit is exhausted and
operations rejected with an HTTP error code 429.
Swift connections can reuse the same session by asking a session
matching their connection parameters with ``get_session``.
The keystoneauth1's session automatically creates a new token
if the previous one is expired.
The best documentation I found about sessions is
https://docs.openstack.org/keystoneauth/latest/using-sessions.html
"""
def __init__(self):
self._sessions = {}
def _get_key(self, auth_url, username, password, tenant_name):
return (auth_url, username, password, tenant_name)
def get_session(self, auth_url=None, username=None, password=None,
tenant_name=None):
key = self._get_key(auth_url, username, password, tenant_name)
session = self._sessions.get(key)
if not session:
auth = keystoneauth1.identity.v2.Password(
username=username,
password=password,
tenant_name=tenant_name,
auth_url=auth_url,
)
session = keystoneauth1.session.Session(
auth=auth,
timeout=SWIFT_TIMEOUT,
)
self._sessions[key] = session
return session
swift_session_store = SwiftSessionStore()
class IrAttachment(models.Model): class IrAttachment(models.Model):
_inherit = 'ir.attachment' _inherit = 'ir.attachment'
@@ -45,15 +96,18 @@ class IrAttachment(models.Model):
"Problem connecting to Swift store, are the env variables " "Problem connecting to Swift store, are the env variables "
"(SWIFT_AUTH_URL, SWIFT_ACCOUNT, SWIFT_PASSWORD, " "(SWIFT_AUTH_URL, SWIFT_ACCOUNT, SWIFT_PASSWORD, "
"SWIFT_TENANT_NAME) properly set?" "SWIFT_TENANT_NAME) properly set?"
)) ))
try: try:
conn = swiftclient.client.Connection(authurl=host, session = swift_session_store.get_session(
user=account, username=account,
key=password, password=password,
tenant_name=tenant_name, tenant_name=tenant_name,
auth_version='2.0', auth_url=host,
os_options=os_options, )
) conn = swiftclient.client.Connection(
session=session,
os_options=os_options,
)
except ClientException: except ClientException:
_logger.exception('Error connecting to Swift object store') _logger.exception('Error connecting to Swift object store')
raise exceptions.UserError(_('Error on Swift connection')) raise exceptions.UserError(_('Error on Swift connection'))
+5 -2
View File
@@ -2,5 +2,8 @@ boto==2.42.0
redis==2.10.5 redis==2.10.5
python-json-logger==0.1.5 python-json-logger==0.1.5
statsd==3.2.1 statsd==3.2.1
python-swiftclient==3.4.0 python-swiftclient==3.7.0
python-keystoneclient==3.13.0 python-keystoneclient==3.19.0
keystoneauth1==3.14.0
# error with 5.x (ConstructorError: could not determine a constructor for the tag '!record')
PyYAML==4.2b4