summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrant Knudson <bknudson@us.ibm.com>2015-06-07 11:20:44 -0500
committerBrant Knudson <bknudson@us.ibm.com>2015-06-30 12:58:55 -0500
commit97c2c690d8983fd1d929a4eae3b0d62bbcb2cf6a (patch)
tree1d21dbde7b1e77c839c749e3a658d461332385d7
parentaa9e413a6def86c58b19495ac6ac439e61d04a8b (diff)
downloadpython-keystoneclient-97c2c690d8983fd1d929a4eae3b0d62bbcb2cf6a.tar.gz
Switch from deprecated isotime
oslo_utils.timeutils.isotime() is deprecated as of 1.6 so we need to stop using it. The deprecation message says to use datetime.datetime.isoformat() instead, but the format of the string generated by isoformat isn't the same as the format of the string generated by isotime. The string is used in tokens and other public APIs and we can't change it without potentially breaking clients. So the workaround is to copy the current implementation from oslo_utils.timeutils.isotime() to keystone.common.utils.isotime(). Change-Id: I34b12b96de3ea21beaf935ed8a9f6bae2fe0d0bc Closes-Bug: 1461251
-rw-r--r--keystoneclient/contrib/revoke/model.py11
-rw-r--r--keystoneclient/fixture/discovery.py2
-rw-r--r--keystoneclient/fixture/v2.py5
-rw-r--r--keystoneclient/fixture/v3.py5
-rw-r--r--keystoneclient/middleware/auth_token.py3
-rw-r--r--keystoneclient/tests/unit/test_auth_token_middleware.py9
-rw-r--r--keystoneclient/tests/unit/test_keyring.py5
-rw-r--r--keystoneclient/utils.py30
-rw-r--r--keystoneclient/v3/contrib/trusts.py5
9 files changed, 56 insertions, 19 deletions
diff --git a/keystoneclient/contrib/revoke/model.py b/keystoneclient/contrib/revoke/model.py
index bb62840..5c17680 100644
--- a/keystoneclient/contrib/revoke/model.py
+++ b/keystoneclient/contrib/revoke/model.py
@@ -12,6 +12,9 @@
from oslo_utils import timeutils
+from keystoneclient import utils
+
+
# The set of attributes common between the RevokeEvent
# and the dictionaries created from the token Data.
_NAMES = ['trust_id',
@@ -75,11 +78,11 @@ class RevokeEvent(object):
if self.consumer_id is not None:
event['OS-OAUTH1:access_token_id'] = self.access_token_id
if self.expires_at is not None:
- event['expires_at'] = timeutils.isotime(self.expires_at,
- subsecond=True)
+ event['expires_at'] = utils.isotime(self.expires_at,
+ subsecond=True)
if self.issued_before is not None:
- event['issued_before'] = timeutils.isotime(self.issued_before,
- subsecond=True)
+ event['issued_before'] = utils.isotime(self.issued_before,
+ subsecond=True)
return event
def key_for_name(self, name):
diff --git a/keystoneclient/fixture/discovery.py b/keystoneclient/fixture/discovery.py
index eae0bcd..50a6bce 100644
--- a/keystoneclient/fixture/discovery.py
+++ b/keystoneclient/fixture/discovery.py
@@ -77,7 +77,7 @@ class DiscoveryBase(dict):
@updated.setter
def updated(self, value):
- self.updated_str = timeutils.isotime(value)
+ self.updated_str = utils.isotime(value)
@utils.positional()
def add_link(self, href, rel='self', type=None):
diff --git a/keystoneclient/fixture/v2.py b/keystoneclient/fixture/v2.py
index 3022f2c..da60b9b 100644
--- a/keystoneclient/fixture/v2.py
+++ b/keystoneclient/fixture/v2.py
@@ -16,6 +16,7 @@ import uuid
from oslo_utils import timeutils
from keystoneclient.fixture import exception
+from keystoneclient import utils
class _Service(dict):
@@ -112,7 +113,7 @@ class Token(dict):
@expires.setter
def expires(self, value):
- self.expires_str = timeutils.isotime(value)
+ self.expires_str = utils.isotime(value)
@property
def issued_str(self):
@@ -128,7 +129,7 @@ class Token(dict):
@issued.setter
def issued(self, value):
- self.issued_str = timeutils.isotime(value)
+ self.issued_str = utils.isotime(value)
@property
def _user(self):
diff --git a/keystoneclient/fixture/v3.py b/keystoneclient/fixture/v3.py
index a1781dd..bda5e19 100644
--- a/keystoneclient/fixture/v3.py
+++ b/keystoneclient/fixture/v3.py
@@ -16,6 +16,7 @@ import uuid
from oslo_utils import timeutils
from keystoneclient.fixture import exception
+from keystoneclient import utils
class _Service(dict):
@@ -136,7 +137,7 @@ class Token(dict):
@expires.setter
def expires(self, value):
- self.expires_str = timeutils.isotime(value, subsecond=True)
+ self.expires_str = utils.isotime(value, subsecond=True)
@property
def issued_str(self):
@@ -152,7 +153,7 @@ class Token(dict):
@issued.setter
def issued(self, value):
- self.issued_str = timeutils.isotime(value, subsecond=True)
+ self.issued_str = utils.isotime(value, subsecond=True)
@property
def _user(self):
diff --git a/keystoneclient/middleware/auth_token.py b/keystoneclient/middleware/auth_token.py
index d0fe102..86cc11a 100644
--- a/keystoneclient/middleware/auth_token.py
+++ b/keystoneclient/middleware/auth_token.py
@@ -169,6 +169,7 @@ from keystoneclient.common import cms
from keystoneclient import exceptions
from keystoneclient.middleware import memcache_crypt
from keystoneclient.openstack.common import memorycache
+from keystoneclient import utils
# alternative middleware configuration in the main application's
@@ -382,7 +383,7 @@ def confirm_token_not_expired(data):
utcnow = timeutils.utcnow()
if utcnow >= expires:
raise InvalidUserToken('Token authorization failed')
- return timeutils.isotime(at=expires, subsecond=True)
+ return utils.isotime(at=expires, subsecond=True)
def _v3_to_v2_catalog(catalog):
diff --git a/keystoneclient/tests/unit/test_auth_token_middleware.py b/keystoneclient/tests/unit/test_auth_token_middleware.py
index 091f956..b6c67fa 100644
--- a/keystoneclient/tests/unit/test_auth_token_middleware.py
+++ b/keystoneclient/tests/unit/test_auth_token_middleware.py
@@ -43,6 +43,7 @@ from keystoneclient.middleware import auth_token
from keystoneclient.openstack.common import memorycache
from keystoneclient.tests.unit import client_fixtures
from keystoneclient.tests.unit import utils
+from keystoneclient import utils as client_utils
EXPECTED_V2_DEFAULT_ENV_RESPONSE = {
@@ -1684,10 +1685,10 @@ class TokenExpirationTest(BaseAuthTokenMiddlewareTest):
super(TokenExpirationTest, self).setUp()
self.now = timeutils.utcnow()
self.delta = datetime.timedelta(hours=1)
- self.one_hour_ago = timeutils.isotime(self.now - self.delta,
- subsecond=True)
- self.one_hour_earlier = timeutils.isotime(self.now + self.delta,
- subsecond=True)
+ self.one_hour_ago = client_utils.isotime(self.now - self.delta,
+ subsecond=True)
+ self.one_hour_earlier = client_utils.isotime(self.now + self.delta,
+ subsecond=True)
def create_v2_token_fixture(self, expires=None):
v2_fixture = {
diff --git a/keystoneclient/tests/unit/test_keyring.py b/keystoneclient/tests/unit/test_keyring.py
index a54009e..4fea794 100644
--- a/keystoneclient/tests/unit/test_keyring.py
+++ b/keystoneclient/tests/unit/test_keyring.py
@@ -19,6 +19,7 @@ from keystoneclient import access
from keystoneclient import httpclient
from keystoneclient.tests.unit import utils
from keystoneclient.tests.unit.v2_0 import client_fixtures
+from keystoneclient import utils as client_utils
try:
import keyring # noqa
@@ -124,7 +125,7 @@ class KeyringTest(utils.TestCase):
# set an expired token into the keyring
auth_ref = access.AccessInfo.factory(body=PROJECT_SCOPED_TOKEN)
expired = timeutils.utcnow() - datetime.timedelta(minutes=30)
- auth_ref['token']['expires'] = timeutils.isotime(expired)
+ auth_ref['token']['expires'] = client_utils.isotime(expired)
self.memory_keyring.password = pickle.dumps(auth_ref)
# stub and check that a new token is received, so not using expired
@@ -152,7 +153,7 @@ class KeyringTest(utils.TestCase):
# set an token into the keyring
auth_ref = access.AccessInfo.factory(body=PROJECT_SCOPED_TOKEN)
future = timeutils.utcnow() + datetime.timedelta(minutes=30)
- auth_ref['token']['expires'] = timeutils.isotime(future)
+ auth_ref['token']['expires'] = client_utils.isotime(future)
self.memory_keyring.password = pickle.dumps(auth_ref)
# don't stub get_raw_token so will fail if authenticate happens
diff --git a/keystoneclient/utils.py b/keystoneclient/utils.py
index 300ca54..3565565 100644
--- a/keystoneclient/utils.py
+++ b/keystoneclient/utils.py
@@ -18,6 +18,7 @@ import logging
import sys
from oslo_utils import encodeutils
+from oslo_utils import timeutils
import prettytable
import six
@@ -336,3 +337,32 @@ class positional(object):
return func(*args, **kwargs)
return inner
+
+
+_ISO8601_TIME_FORMAT_SUBSECOND = '%Y-%m-%dT%H:%M:%S.%f'
+_ISO8601_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S'
+
+
+def isotime(at=None, subsecond=False):
+ """Stringify time in ISO 8601 format."""
+
+ # Python provides a similar instance method for datetime.datetime objects
+ # called isoformat(). The format of the strings generated by isoformat()
+ # have a couple of problems:
+ # 1) The strings generated by isotime are used in tokens and other public
+ # APIs that we can't change without a deprecation period. The strings
+ # generated by isoformat are not the same format, so we can't just
+ # change to it.
+ # 2) The strings generated by isoformat do not include the microseconds if
+ # the value happens to be 0. This will likely show up as random failures
+ # as parsers may be written to always expect microseconds, and it will
+ # parse correctly most of the time.
+
+ if not at:
+ at = timeutils.utcnow()
+ st = at.strftime(_ISO8601_TIME_FORMAT
+ if not subsecond
+ else _ISO8601_TIME_FORMAT_SUBSECOND)
+ tz = at.tzinfo.tzname(None) if at.tzinfo else 'UTC'
+ st += ('Z' if tz == 'UTC' else tz)
+ return st
diff --git a/keystoneclient/v3/contrib/trusts.py b/keystoneclient/v3/contrib/trusts.py
index 5fe88f8..1b3033c 100644
--- a/keystoneclient/v3/contrib/trusts.py
+++ b/keystoneclient/v3/contrib/trusts.py
@@ -10,11 +10,10 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_utils import timeutils
-
from keystoneclient import base
from keystoneclient import exceptions
from keystoneclient.i18n import _
+from keystoneclient import utils
class Trust(base.Resource):
@@ -61,7 +60,7 @@ class TrustManager(base.CrudManager):
# Convert datetime.datetime expires_at to iso format string
if expires_at:
- expires_str = timeutils.isotime(at=expires_at, subsecond=True)
+ expires_str = utils.isotime(at=expires_at, subsecond=True)
else:
expires_str = None