openstack-common: timeutils and importutils seperated out
Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
This commit is contained in:
parent
a9a6906a6e
commit
1f141a6d04
@ -17,7 +17,7 @@
|
||||
Middleware that attaches a context to the WSGI request
|
||||
"""
|
||||
|
||||
from heat.common import utils
|
||||
from heat.common import importutils
|
||||
from heat.common import wsgi
|
||||
from heat.common import context
|
||||
|
||||
@ -35,7 +35,7 @@ class ContextMiddleware(wsgi.Middleware):
|
||||
# Determine the context class to use
|
||||
ctxcls = context.RequestContext
|
||||
if 'context_class' in self.options:
|
||||
ctxcls = utils.import_class(self.options['context_class'])
|
||||
ctxcls = importutils.import_class(self.options['context_class'])
|
||||
|
||||
return ctxcls(*args, **kwargs)
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
from heat.common import exception
|
||||
from heat.common import wsgi
|
||||
from heat.openstack.common import cfg
|
||||
from heat.openstack.common import utils
|
||||
from heat.openstack.common import importutils
|
||||
|
||||
|
||||
class RequestContext(object):
|
||||
@ -64,7 +64,7 @@ class ContextMiddleware(wsgi.Middleware):
|
||||
# Determine the context class to use
|
||||
self.ctxcls = RequestContext
|
||||
if 'context_class' in local_conf:
|
||||
self.ctxcls = utils.import_class(local_conf['context_class'])
|
||||
self.ctxcls = importutils.import_class(local_conf['context_class'])
|
||||
|
||||
super(ContextMiddleware, self).__init__(app)
|
||||
|
||||
|
@ -30,6 +30,7 @@ from eventlet import semaphore
|
||||
from eventlet.green import subprocess
|
||||
|
||||
from heat.openstack.common import exception
|
||||
from heat.openstack.common import timeutils
|
||||
|
||||
PERFECT_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%f"
|
||||
|
||||
@ -71,7 +72,7 @@ def gen_uuid():
|
||||
def strtime(at=None, fmt=PERFECT_TIME_FORMAT):
|
||||
"""Returns formatted utcnow."""
|
||||
if not at:
|
||||
at = utcnow()
|
||||
at = timeutils.utcnow()
|
||||
return at.strftime(fmt)
|
||||
|
||||
|
||||
@ -80,16 +81,6 @@ def parse_strtime(timestr, fmt=PERFECT_TIME_FORMAT):
|
||||
return datetime.datetime.strptime(timestr, fmt)
|
||||
|
||||
|
||||
def isotime(at=None):
|
||||
"""Stringify time in ISO 8601 format"""
|
||||
if not at:
|
||||
at = datetime.datetime.utcnow()
|
||||
str = at.strftime(ISO_TIME_FORMAT)
|
||||
tz = at.tzinfo.tzname(None) if at.tzinfo else 'UTC'
|
||||
str += ('Z' if tz == 'UTC' else tz)
|
||||
return str
|
||||
|
||||
|
||||
class LoopingCallDone(Exception):
|
||||
"""Exception to break out and stop a LoopingCall.
|
||||
|
||||
|
@ -41,6 +41,7 @@ import webob.exc
|
||||
|
||||
from heat.common import exception
|
||||
from heat.openstack.common import cfg
|
||||
from heat.openstack.common import importutils
|
||||
from heat.openstack.common import utils
|
||||
|
||||
bind_opts = [
|
||||
@ -544,7 +545,7 @@ class BasePasteFactory(object):
|
||||
we strip() the value before using it.
|
||||
"""
|
||||
class_name = local_conf[self.KEY].replace(':', '.').strip()
|
||||
return utils.import_class(class_name)
|
||||
return importutils.import_class(class_name)
|
||||
|
||||
|
||||
class AppFactory(BasePasteFactory):
|
||||
|
@ -24,6 +24,7 @@ import logging
|
||||
|
||||
from heat.openstack.common import local
|
||||
from heat.openstack.common import utils
|
||||
from heat.openstack.common import timeutils
|
||||
|
||||
from heat.common import utils as heat_utils
|
||||
|
||||
@ -73,7 +74,7 @@ class RequestContext(object):
|
||||
self.read_deleted = read_deleted
|
||||
self.remote_address = remote_address
|
||||
if not timestamp:
|
||||
timestamp = utils.utcnow()
|
||||
timestamp = timeutils.utcnow()
|
||||
if isinstance(timestamp, basestring):
|
||||
timestamp = heat_utils.parse_strtime(timestamp)
|
||||
self.timestamp = timestamp
|
||||
|
@ -22,7 +22,7 @@ from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.schema import ForeignKeyConstraint
|
||||
from sqlalchemy import types as types
|
||||
from json import dumps, loads
|
||||
from heat.openstack.common import utils
|
||||
from heat.openstack.common import timeutils
|
||||
from heat.db.sqlalchemy.session import get_session
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
@ -43,8 +43,8 @@ class HeatBase(object):
|
||||
"""Base class for Heat Models."""
|
||||
__table_args__ = {'mysql_engine': 'InnoDB'}
|
||||
__table_initialized__ = False
|
||||
created_at = Column(DateTime, default=utils.utcnow)
|
||||
updated_at = Column(DateTime, onupdate=utils.utcnow)
|
||||
created_at = Column(DateTime, default=timeutils.utcnow)
|
||||
updated_at = Column(DateTime, onupdate=timeutils.utcnow)
|
||||
|
||||
def save(self, session=None):
|
||||
"""Save this object."""
|
||||
@ -64,7 +64,7 @@ class HeatBase(object):
|
||||
def delete(self, session=None):
|
||||
"""Delete this object."""
|
||||
self.deleted = True
|
||||
self.deleted_at = utils.utcnow()
|
||||
self.deleted_at = timeutils.utcnow()
|
||||
self.save(session=session)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
|
45
heat/openstack/common/importutils.py
Normal file
45
heat/openstack/common/importutils.py
Normal file
@ -0,0 +1,45 @@
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Import related utilities and helper functions.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
from heat.openstack.common import exception
|
||||
|
||||
|
||||
def import_class(import_str):
|
||||
"""Returns a class from a string including module and class"""
|
||||
mod_str, _sep, class_str = import_str.rpartition('.')
|
||||
try:
|
||||
__import__(mod_str)
|
||||
return getattr(sys.modules[mod_str], class_str)
|
||||
except (ImportError, ValueError, AttributeError):
|
||||
raise exception.NotFound('Class %s cannot be found' % class_str)
|
||||
|
||||
|
||||
def import_object(import_str, *args, **kwargs):
|
||||
"""Import a class and return an instance of it."""
|
||||
return import_class(import_str)(*args, **kwargs)
|
||||
|
||||
|
||||
def import_module(import_str):
|
||||
"""Import a module."""
|
||||
__import__(import_str)
|
||||
return sys.modules[import_str]
|
73
heat/openstack/common/timeutils.py
Normal file
73
heat/openstack/common/timeutils.py
Normal file
@ -0,0 +1,73 @@
|
||||
# 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 datetime
|
||||
|
||||
import iso8601
|
||||
|
||||
|
||||
TIME_FORMAT = "%Y-%m-%dT%H:%M:%S"
|
||||
|
||||
|
||||
def isotime(at=None):
|
||||
"""Stringify time in ISO 8601 format"""
|
||||
if not at:
|
||||
at = datetime.datetime.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 normalize_time(timestamp):
|
||||
"""Normalize time in arbitrary timezone to UTC"""
|
||||
offset = timestamp.utcoffset()
|
||||
return timestamp.replace(tzinfo=None) - offset if offset else timestamp
|
||||
|
||||
|
||||
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 clear_time_override():
|
||||
"""Remove the overridden time."""
|
||||
utcnow.override_time = None
|
@ -19,21 +19,17 @@
|
||||
System-level utilities and helper functions.
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import shlex
|
||||
import sys
|
||||
|
||||
from eventlet import greenthread
|
||||
from eventlet.green import subprocess
|
||||
import iso8601
|
||||
|
||||
from heat.openstack.common import exception
|
||||
|
||||
|
||||
TIME_FORMAT = "%Y-%m-%dT%H:%M:%S"
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -142,92 +138,3 @@ def execute(*cmd, **kwargs):
|
||||
# call clean something up in between calls, without
|
||||
# it two execute calls in a row hangs the second one
|
||||
greenthread.sleep(0)
|
||||
|
||||
|
||||
def import_class(import_str):
|
||||
"""Returns a class from a string including module and class"""
|
||||
mod_str, _sep, class_str = import_str.rpartition('.')
|
||||
try:
|
||||
__import__(mod_str)
|
||||
return getattr(sys.modules[mod_str], class_str)
|
||||
except (ImportError, ValueError, AttributeError):
|
||||
raise exception.NotFound('Class %s cannot be found' % class_str)
|
||||
|
||||
|
||||
def import_object(import_str):
|
||||
"""Returns an object including a module or module and class"""
|
||||
try:
|
||||
__import__(import_str)
|
||||
return sys.modules[import_str]
|
||||
except ImportError:
|
||||
return import_class(import_str)
|
||||
|
||||
|
||||
def isotime(at=None):
|
||||
"""Stringify time in ISO 8601 format"""
|
||||
if not at:
|
||||
at = datetime.datetime.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 normalize_time(timestamp):
|
||||
"""Normalize time in arbitrary timezone to UTC"""
|
||||
offset = timestamp.utcoffset()
|
||||
return timestamp.replace(tzinfo=None) - offset if offset else timestamp
|
||||
|
||||
|
||||
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 clear_time_override():
|
||||
"""Remove the overridden time."""
|
||||
utcnow.override_time = None
|
||||
|
||||
|
||||
def auth_str_equal(provided, known):
|
||||
"""Constant-time string comparison.
|
||||
|
||||
:params provided: the first string
|
||||
:params known: the second string
|
||||
|
||||
:return: True if the strings are equal.
|
||||
|
||||
This function takes two strings and compares them. It is intended to be
|
||||
used when doing a comparison for authentication purposes to help guard
|
||||
against timing attacks. When using the function for this purpose, always
|
||||
provide the user-provided password as the first argument. The time this
|
||||
function will take is always a factor of the length of this string.
|
||||
"""
|
||||
result = 0
|
||||
p_len = len(provided)
|
||||
k_len = len(known)
|
||||
for i in xrange(p_len):
|
||||
a = ord(provided[i]) if i < p_len else 0
|
||||
b = ord(known[i]) if i < k_len else 0
|
||||
result |= a ^ b
|
||||
return (p_len == k_len) & (result == 0)
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
import logging
|
||||
from heat.openstack.common import cfg
|
||||
from heat.openstack.common import utils
|
||||
from heat.openstack.common import importutils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -192,7 +192,7 @@ def configure(conf):
|
||||
LOG.debug(_("Configuring RPC %s") % conf.rpc_backend)
|
||||
|
||||
global _RPCIMPL
|
||||
_RPCIMPL = utils.import_object(conf.rpc_backend)
|
||||
_RPCIMPL = importutils.import_module(conf.rpc_backend)
|
||||
|
||||
|
||||
def _get_impl():
|
||||
|
@ -27,7 +27,7 @@ import logging
|
||||
import greenlet
|
||||
|
||||
from heat.openstack.common import cfg
|
||||
from heat.openstack.common import utils
|
||||
from heat.openstack.common import importutils
|
||||
|
||||
from heat.common import utils as heat_utils
|
||||
from heat.common import exception
|
||||
@ -108,7 +108,7 @@ class Service(object):
|
||||
self.binary = binary
|
||||
self.topic = topic
|
||||
self.manager_class_name = manager
|
||||
manager_class = utils.import_class(self.manager_class_name)
|
||||
manager_class = importutils.import_class(self.manager_class_name)
|
||||
self.manager = manager_class(host=self.host, *args, **kwargs)
|
||||
self.periodic_interval = periodic_interval
|
||||
super(Service, self).__init__(*args, **kwargs)
|
||||
|
@ -1,7 +1,7 @@
|
||||
[DEFAULT]
|
||||
|
||||
# The list of modules to copy from openstack-common
|
||||
modules=cfg,local,iniparser,utils,exception
|
||||
modules=cfg,local,iniparser,utils,exception,timeutils,importutils
|
||||
|
||||
# The base module to hold the copy of openstack.common
|
||||
base=heat
|
||||
|
Loading…
Reference in New Issue
Block a user