Currently tox ignores D400. D400: First line should end with a period. This change removes it and make keystoneclient docstrings compliant with it. Change-Id: I29ecb4c58bb03c0b9a3be0b7a74d18fb06a350f2
		
			
				
	
	
		
			157 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			157 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#    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 getpass
 | 
						|
import hashlib
 | 
						|
import logging
 | 
						|
import sys
 | 
						|
 | 
						|
from oslo_utils import timeutils
 | 
						|
# NOTE(stevemar): do not remove positional. We need this to stay for a while
 | 
						|
# since versions of auth_token require it here.
 | 
						|
from positional import positional  # noqa
 | 
						|
import six
 | 
						|
 | 
						|
from keystoneclient import exceptions
 | 
						|
 | 
						|
 | 
						|
logger = logging.getLogger(__name__)
 | 
						|
 | 
						|
 | 
						|
def find_resource(manager, name_or_id):
 | 
						|
    """Helper for the _find_* methods."""
 | 
						|
 | 
						|
    # first try the entity as a string
 | 
						|
    try:
 | 
						|
        return manager.get(name_or_id)
 | 
						|
    except (exceptions.NotFound):  # nosec(cjschaef): try to find 'name_or_id'
 | 
						|
        # as a six.binary_type instead
 | 
						|
        pass
 | 
						|
 | 
						|
    # finally try to find entity by name
 | 
						|
    try:
 | 
						|
        if isinstance(name_or_id, six.binary_type):
 | 
						|
            name_or_id = name_or_id.decode('utf-8', 'strict')
 | 
						|
        return manager.find(name=name_or_id)
 | 
						|
    except exceptions.NotFound:
 | 
						|
        msg = ("No %s with a name or ID of '%s' exists." %
 | 
						|
               (manager.resource_class.__name__.lower(), name_or_id))
 | 
						|
        raise exceptions.CommandError(msg)
 | 
						|
    except exceptions.NoUniqueMatch:
 | 
						|
        msg = ("Multiple %s matches found for '%s', use an ID to be more"
 | 
						|
               " specific." % (manager.resource_class.__name__.lower(),
 | 
						|
                               name_or_id))
 | 
						|
        raise exceptions.CommandError(msg)
 | 
						|
 | 
						|
 | 
						|
def unauthenticated(f):
 | 
						|
    """Add 'unauthenticated' attribute to decorated function.
 | 
						|
 | 
						|
    Usage::
 | 
						|
 | 
						|
        @unauthenticated
 | 
						|
        def mymethod(f):
 | 
						|
            ...
 | 
						|
    """
 | 
						|
    f.unauthenticated = True
 | 
						|
    return f
 | 
						|
 | 
						|
 | 
						|
def isunauthenticated(f):
 | 
						|
    """Check if function requires authentication.
 | 
						|
 | 
						|
    Checks to see if the function is marked as not requiring authentication
 | 
						|
    with the @unauthenticated decorator.
 | 
						|
 | 
						|
    Returns True if decorator is set to True, False otherwise.
 | 
						|
    """
 | 
						|
    return getattr(f, 'unauthenticated', False)
 | 
						|
 | 
						|
 | 
						|
def hash_signed_token(signed_text, mode='md5'):
 | 
						|
    hash_ = hashlib.new(mode)
 | 
						|
    hash_.update(signed_text)
 | 
						|
    return hash_.hexdigest()
 | 
						|
 | 
						|
 | 
						|
def prompt_user_password():
 | 
						|
    """Prompt user for a password.
 | 
						|
 | 
						|
    Prompt for a password if stdin is a tty.
 | 
						|
    """
 | 
						|
    password = None
 | 
						|
 | 
						|
    # If stdin is a tty, try prompting for the password
 | 
						|
    if hasattr(sys.stdin, 'isatty') and sys.stdin.isatty():
 | 
						|
        # Check for Ctl-D
 | 
						|
        try:
 | 
						|
            password = getpass.getpass('Password: ')
 | 
						|
        except EOFError:  # nosec(cjschaef): return password, which is None if
 | 
						|
            # password was not found
 | 
						|
            pass
 | 
						|
 | 
						|
    return password
 | 
						|
 | 
						|
 | 
						|
def prompt_for_password():
 | 
						|
    """Prompt user for password if not provided.
 | 
						|
 | 
						|
    Prompt is used so the password doesn't show up in the
 | 
						|
    bash history.
 | 
						|
    """
 | 
						|
    if not (hasattr(sys.stdin, 'isatty') and sys.stdin.isatty()):
 | 
						|
        # nothing to do
 | 
						|
        return
 | 
						|
 | 
						|
    while True:
 | 
						|
        try:
 | 
						|
            new_passwd = getpass.getpass('New Password: ')
 | 
						|
            rep_passwd = getpass.getpass('Repeat New Password: ')
 | 
						|
            if new_passwd == rep_passwd:
 | 
						|
                return new_passwd
 | 
						|
        except EOFError:
 | 
						|
            return
 | 
						|
 | 
						|
 | 
						|
_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
 | 
						|
 | 
						|
 | 
						|
def strtime(at=None):
 | 
						|
    at = at or timeutils.utcnow()
 | 
						|
    return at.strftime(timeutils.PERFECT_TIME_FORMAT)
 |