Keystone should use openstack.common.timeutils
Implements blueprint use-common-timeutils 1. Edit openstack-common.conf and import keystone/openstack/common/timeutils.py 2. Replace datetime.utcnow with timeutils.utcnow 3. Replace utils.isotime with timeutils.isotime 4. Remove utils.isotime in common/utils.py and datetime related unittest Change-Id: I4f5a63a368fde8787a0dc0a817c940de685b9ca2
This commit is contained in:
parent
8cd73c75ce
commit
c79d93bfbc
@ -39,7 +39,6 @@ config.register_int('crypt_strength', default=40000)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
ISO_TIME_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
|
||||
MAX_PASSWORD_LENGTH = 4096
|
||||
|
||||
|
||||
@ -232,16 +231,6 @@ def git(*args):
|
||||
return check_output(['git'] + list(args))
|
||||
|
||||
|
||||
def isotime(dt_obj):
|
||||
"""Format datetime object as ISO compliant string.
|
||||
|
||||
:param dt_obj: datetime.datetime object
|
||||
:returns: string representation of datetime object
|
||||
|
||||
"""
|
||||
return dt_obj.strftime(ISO_TIME_FORMAT)
|
||||
|
||||
|
||||
def unixtime(dt_obj):
|
||||
"""Format datetime object as unix timestamp
|
||||
|
||||
|
109
keystone/openstack/common/timeutils.py
Normal file
109
keystone/openstack/common/timeutils.py
Normal file
@ -0,0 +1,109 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
Time related utilities and helper functions.
|
||||
"""
|
||||
|
||||
import calendar
|
||||
import datetime
|
||||
import time
|
||||
|
||||
import iso8601
|
||||
|
||||
|
||||
TIME_FORMAT = "%Y-%m-%dT%H:%M:%S"
|
||||
PERFECT_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%f"
|
||||
|
||||
|
||||
def isotime(at=None):
|
||||
"""Stringify time in ISO 8601 format"""
|
||||
if not at:
|
||||
at = utcnow()
|
||||
str = at.strftime(TIME_FORMAT)
|
||||
tz = at.tzinfo.tzname(None) if at.tzinfo else 'UTC'
|
||||
str += ('Z' if tz == 'UTC' else tz)
|
||||
return str
|
||||
|
||||
|
||||
def parse_isotime(timestr):
|
||||
"""Parse time from ISO 8601 format"""
|
||||
try:
|
||||
return iso8601.parse_date(timestr)
|
||||
except iso8601.ParseError as e:
|
||||
raise ValueError(e.message)
|
||||
except TypeError as e:
|
||||
raise ValueError(e.message)
|
||||
|
||||
|
||||
def strtime(at=None, fmt=PERFECT_TIME_FORMAT):
|
||||
"""Returns formatted utcnow."""
|
||||
if not at:
|
||||
at = utcnow()
|
||||
return at.strftime(fmt)
|
||||
|
||||
|
||||
def parse_strtime(timestr, fmt=PERFECT_TIME_FORMAT):
|
||||
"""Turn a formatted time back into a datetime."""
|
||||
return datetime.datetime.strptime(timestr, fmt)
|
||||
|
||||
|
||||
def normalize_time(timestamp):
|
||||
"""Normalize time in arbitrary timezone to UTC"""
|
||||
offset = timestamp.utcoffset()
|
||||
return timestamp.replace(tzinfo=None) - offset if offset else timestamp
|
||||
|
||||
|
||||
def is_older_than(before, seconds):
|
||||
"""Return True if before is older than seconds."""
|
||||
return utcnow() - before > datetime.timedelta(seconds=seconds)
|
||||
|
||||
|
||||
def utcnow_ts():
|
||||
"""Timestamp version of our utcnow function."""
|
||||
return calendar.timegm(utcnow().timetuple())
|
||||
|
||||
|
||||
def utcnow():
|
||||
"""Overridable version of utils.utcnow."""
|
||||
if utcnow.override_time:
|
||||
return utcnow.override_time
|
||||
return datetime.datetime.utcnow()
|
||||
|
||||
|
||||
utcnow.override_time = None
|
||||
|
||||
|
||||
def set_time_override(override_time=datetime.datetime.utcnow()):
|
||||
"""Override utils.utcnow to return a constant time."""
|
||||
utcnow.override_time = override_time
|
||||
|
||||
|
||||
def advance_time_delta(timedelta):
|
||||
"""Advance overriden time using a datetime.timedelta."""
|
||||
assert(not utcnow.override_time is None)
|
||||
utcnow.override_time += timedelta
|
||||
|
||||
|
||||
def advance_time_seconds(seconds):
|
||||
"""Advance overriden time by seconds."""
|
||||
advance_time_delta(datetime.timedelta(0, seconds))
|
||||
|
||||
|
||||
def clear_time_override():
|
||||
"""Remove the overridden time."""
|
||||
utcnow.override_time = None
|
@ -24,6 +24,7 @@ from keystone.common import utils
|
||||
from keystone.common import wsgi
|
||||
from keystone import exception
|
||||
from keystone import identity
|
||||
from keystone.openstack.common import timeutils
|
||||
from keystone import policy
|
||||
from keystone import token
|
||||
|
||||
@ -451,7 +452,7 @@ class TokenController(wsgi.Application):
|
||||
metadata_ref = token_ref['metadata']
|
||||
expires = token_ref['expires']
|
||||
if expires is not None:
|
||||
expires = utils.isotime(expires)
|
||||
expires = timeutils.isotime(expires)
|
||||
o = {'access': {'token': {'id': token_ref['id'],
|
||||
'expires': expires,
|
||||
},
|
||||
|
@ -15,10 +15,10 @@
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
import datetime
|
||||
|
||||
from keystone.common import kvs
|
||||
from keystone import exception
|
||||
from keystone.openstack.common import timeutils
|
||||
from keystone import token
|
||||
|
||||
|
||||
@ -29,8 +29,7 @@ class Token(kvs.Base, token.Driver):
|
||||
token = self.db.get('token-%s' % token_id)
|
||||
except exception.NotFound:
|
||||
raise exception.TokenNotFound(token_id=token_id)
|
||||
if (token['expires'] is None
|
||||
or token['expires'] > datetime.datetime.utcnow()):
|
||||
if token['expires'] is None or token['expires'] > timeutils.utcnow():
|
||||
return token
|
||||
else:
|
||||
raise exception.TokenNotFound(token_id=token_id)
|
||||
@ -50,7 +49,7 @@ class Token(kvs.Base, token.Driver):
|
||||
|
||||
def list_tokens(self, user_id):
|
||||
tokens = []
|
||||
now = datetime.datetime.utcnow()
|
||||
now = timeutils.utcnow()
|
||||
for token, user_ref in self.db.items():
|
||||
if not token.startswith('token-'):
|
||||
continue
|
||||
|
@ -15,10 +15,10 @@
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
import datetime
|
||||
|
||||
from keystone.common import sql
|
||||
from keystone import exception
|
||||
from keystone.openstack.common import timeutils
|
||||
from keystone import token
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ class Token(sql.Base, token.Driver):
|
||||
def get_token(self, token_id):
|
||||
session = self.get_session()
|
||||
token_ref = session.query(TokenModel).filter_by(id=token_id).first()
|
||||
now = datetime.datetime.utcnow()
|
||||
now = timeutils.utcnow()
|
||||
if token_ref and (not token_ref.expires or now < token_ref.expires):
|
||||
return token_ref.to_dict()
|
||||
else:
|
||||
@ -80,7 +80,7 @@ class Token(sql.Base, token.Driver):
|
||||
def list_tokens(self, user_id):
|
||||
session = self.get_session()
|
||||
tokens = []
|
||||
now = datetime.datetime.utcnow()
|
||||
now = timeutils.utcnow()
|
||||
for token_ref in session.query(TokenModel)\
|
||||
.filter(TokenModel.expires > now):
|
||||
token_ref_dict = token_ref.to_dict()
|
||||
|
@ -21,6 +21,7 @@ import datetime
|
||||
from keystone.common import manager
|
||||
from keystone import config
|
||||
from keystone import exception
|
||||
from keystone.openstack.common import timeutils
|
||||
|
||||
|
||||
CONF = config.CONF
|
||||
@ -104,4 +105,4 @@ class Driver(object):
|
||||
|
||||
"""
|
||||
expire_delta = datetime.timedelta(seconds=CONF.token.expiration)
|
||||
return datetime.datetime.utcnow() + expire_delta
|
||||
return timeutils.utcnow() + expire_delta
|
||||
|
@ -1,7 +1,7 @@
|
||||
[DEFAULT]
|
||||
|
||||
# The list of modules to copy from openstack-common
|
||||
modules=cfg,importutils,iniparser,jsonutils,setup
|
||||
modules=cfg,importutils,iniparser,jsonutils,setup,timeutils
|
||||
|
||||
# The base module to hold the copy of openstack.common
|
||||
base=keystone
|
||||
|
@ -18,6 +18,7 @@ import datetime
|
||||
import uuid
|
||||
|
||||
from keystone import exception
|
||||
from keystone.openstack.common import timeutils
|
||||
|
||||
|
||||
class IdentityTests(object):
|
||||
@ -553,8 +554,7 @@ class TokenTests(object):
|
||||
|
||||
def test_expired_token(self):
|
||||
token_id = uuid.uuid4().hex
|
||||
expire_time = datetime.datetime.utcnow() - datetime.timedelta(
|
||||
minutes=1)
|
||||
expire_time = timeutils.utcnow() - datetime.timedelta(minutes=1)
|
||||
data = {'id': token_id, 'a': 'b', 'expires': expire_time}
|
||||
data_ref = self.token_api.create_token(token_id, data)
|
||||
self.assertDictEqual(data_ref, data)
|
||||
|
@ -14,13 +14,13 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import datetime
|
||||
import time
|
||||
import uuid
|
||||
|
||||
import memcache
|
||||
|
||||
from keystone.common import utils
|
||||
from keystone import exception
|
||||
from keystone.openstack.common import timeutils
|
||||
from keystone import test
|
||||
from keystone.token.backends import memcache as token_memcache
|
||||
|
||||
@ -42,7 +42,7 @@ class MemcacheClient(object):
|
||||
"""Retrieves the value for a key or None."""
|
||||
self.check_key(key)
|
||||
obj = self.cache.get(key)
|
||||
now = time.mktime(datetime.datetime.utcnow().utctimetuple())
|
||||
now = utils.unixtime(timeutils.utcnow())
|
||||
if obj and (obj[1] == 0 or obj[1] > now):
|
||||
return obj[0]
|
||||
else:
|
||||
|
@ -29,8 +29,6 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import datetime
|
||||
|
||||
from keystone import test
|
||||
from keystone.common import utils
|
||||
|
||||
@ -60,13 +58,6 @@ class UtilsTestCase(test.TestCase):
|
||||
self.assertTrue(utils.check_password(password, hashed))
|
||||
self.assertFalse(utils.check_password(wrong, hashed))
|
||||
|
||||
def test_isotime(self):
|
||||
dt = datetime.datetime(year=1987, month=10, day=13,
|
||||
hour=1, minute=2, second=3)
|
||||
output = utils.isotime(dt)
|
||||
expected = '1987-10-13T01:02:03Z'
|
||||
self.assertEqual(output, expected)
|
||||
|
||||
def test_auth_str_equal(self):
|
||||
self.assertTrue(utils.auth_str_equal('abc123', 'abc123'))
|
||||
self.assertFalse(utils.auth_str_equal('a', 'aaaaa'))
|
||||
|
Loading…
Reference in New Issue
Block a user