<s> import functools <EOL> import logging <EOL> import os <EOL> import pkgutil <EOL> import re <EOL> from oslo_utils import strutils <EOL> import cinderclient <EOL> from cinderclient import exceptions <EOL> from cinderclient import utils <EOL> from cinderclient . _i18n import _ <EOL> logging . basicConfig ( ) <EOL> LOG = logging . getLogger ( __name__ ) <EOL> if not LOG . handlers : <EOL> LOG . addHandler ( logging . StreamHandler ( ) ) <EOL> DEPRECATED_VERSIONS = { "<STR_LIT:1>" : "<STR_LIT:2>" } <EOL> MAX_VERSION = "<STR_LIT>" <EOL> _SUBSTITUTIONS = { } <EOL> _type_error_msg = "<STR_LIT>" <EOL> class APIVersion ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , version_str = None ) : <EOL> """<STR_LIT>""" <EOL> self . ver_major = <NUM_LIT:0> <EOL> self . ver_minor = <NUM_LIT:0> <EOL> if version_str is not None : <EOL> match = re . match ( r"<STR_LIT>" , version_str ) <EOL> if match : <EOL> self . ver_major = int ( match . group ( <NUM_LIT:1> ) ) <EOL> if match . group ( <NUM_LIT:2> ) == "<STR_LIT>" : <EOL> self . ver_minor = float ( "<STR_LIT>" ) <EOL> else : <EOL> self . ver_minor = int ( match . group ( <NUM_LIT:2> ) ) <EOL> else : <EOL> msg = ( _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) % version_str ) <EOL> raise exceptions . UnsupportedVersion ( msg ) <EOL> def __str__ ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . is_latest ( ) : <EOL> return "<STR_LIT>" % self . ver_major <EOL> return ( "<STR_LIT>" <EOL> % ( self . ver_major , self . ver_minor ) ) <EOL> def __repr__ ( self ) : <EOL> if self . is_null ( ) : <EOL> return "<STR_LIT>" <EOL> else : <EOL> return "<STR_LIT>" % self . get_string ( ) <EOL> def is_null ( self ) : <EOL> return self . ver_major == <NUM_LIT:0> and self . ver_minor == <NUM_LIT:0> <EOL> def is_latest ( self ) : <EOL> return self . ver_minor == float ( "<STR_LIT>" ) <EOL> def __lt__ ( self , other ) : <EOL> if not isinstance ( other , APIVersion ) : <EOL> raise TypeError ( _type_error_msg % { "<STR_LIT>" : other , <EOL> "<STR_LIT>" : self . __class__ } ) <EOL> return ( ( self . ver_major , self . ver_minor ) < <EOL> ( other . ver_major , other . ver_minor ) ) <EOL> def __eq__ ( self , other ) : <EOL> if not isinstance ( other , APIVersion ) : <EOL> raise TypeError ( _type_error_msg % { "<STR_LIT>" : other , <EOL> "<STR_LIT>" : self . __class__ } ) <EOL> return ( ( self . ver_major , self . ver_minor ) == <EOL> ( other . ver_major , other . ver_minor ) ) <EOL> def __gt__ ( self , other ) : <EOL> if not isinstance ( other , APIVersion ) : <EOL> raise TypeError ( _type_error_msg % { "<STR_LIT>" : other , <EOL> "<STR_LIT>" : self . __class__ } ) <EOL> return ( ( self . ver_major , self . ver_minor ) > <EOL> ( other . ver_major , other . ver_minor ) ) <EOL> def __le__ ( self , other ) : <EOL> return self < other or self == other <EOL> def __ne__ ( self , other ) : <EOL> return not self . __eq__ ( other ) <EOL> def __ge__ ( self , other ) : <EOL> return self > other or self == other <EOL> def matches ( self , min_version , max_version = None ) : <EOL> """<STR_LIT>""" <EOL> if self . is_null ( ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> if isinstance ( min_version , str ) : <EOL> min_version = APIVersion ( version_str = min_version ) <EOL> if isinstance ( max_version , str ) : <EOL> max_version = APIVersion ( version_str = max_version ) <EOL> if not min_version and not max_version : <EOL> return True <EOL> elif ( ( min_version and max_version ) and <EOL> max_version . is_null ( ) and min_version . is_null ( ) ) : <EOL> return True <EOL> elif not max_version or max_version . is_null ( ) : <EOL> return min_version <= self <EOL> elif not min_version or min_version . is_null ( ) : <EOL> return self <= max_version <EOL> else : <EOL> return min_version <= self <= max_version <EOL> def get_string ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . is_null ( ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> elif self . is_latest ( ) : <EOL> return "<STR_LIT>" % ( self . ver_major , "<STR_LIT>" ) <EOL> return "<STR_LIT>" % ( self . ver_major , self . ver_minor ) <EOL> class VersionedMethod ( object ) : <EOL> def __init__ ( self , name , start_version , end_version , func ) : <EOL> """<STR_LIT>""" <EOL> self . name = name <EOL> self . start_version = start_version <EOL> self . end_version = end_version <EOL> self . func = func <EOL> def __str__ ( self ) : <EOL> return ( "<STR_LIT>" <EOL> % ( self . name , self . start_version , self . end_version ) ) <EOL> def __repr__ ( self ) : <EOL> return "<STR_LIT>" % self . name <EOL> def get_available_major_versions ( ) : <EOL> matcher = re . compile ( r"<STR_LIT>" ) <EOL> submodules = pkgutil . iter_modules ( [ os . path . dirname ( __file__ ) ] ) <EOL> available_versions = [ name [ <NUM_LIT:1> : ] for loader , name , ispkg in submodules <EOL> if matcher . search ( name ) ] <EOL> return available_versions <EOL> def check_major_version ( api_version ) : <EOL> """<STR_LIT>""" <EOL> available_versions = get_available_major_versions ( ) <EOL> if ( not api_version . is_null ( ) and <EOL> str ( api_version . ver_major ) not in available_versions ) : <EOL> if len ( available_versions ) == <NUM_LIT:1> : <EOL> msg = ( "<STR_LIT>" <EOL> "<STR_LIT>" ) % { <EOL> "<STR_LIT:version>" : api_version . get_string ( ) , <EOL> "<STR_LIT>" : available_versions [ <NUM_LIT:0> ] } <EOL> else : <EOL> msg = ( "<STR_LIT>" <EOL> "<STR_LIT>" ) % { <EOL> "<STR_LIT:version>" : api_version . get_string ( ) , <EOL> "<STR_LIT>" : "<STR_LIT:U+002CU+0020>" . join ( available_versions ) } <EOL> raise exceptions . UnsupportedVersion ( msg ) <EOL> def get_api_version ( version_string ) : <EOL> """<STR_LIT>""" <EOL> version_string = str ( version_string ) <EOL> if version_string in DEPRECATED_VERSIONS : <EOL> LOG . warning ( "<STR_LIT>" <EOL> "<STR_LIT>" % <EOL> { "<STR_LIT>" : version_string , <EOL> "<STR_LIT>" : DEPRECATED_VERSIONS [ version_string ] } ) <EOL> if strutils . is_int_like ( version_string ) : <EOL> version_string = "<STR_LIT>" % version_string <EOL> api_version = APIVersion ( version_string ) <EOL> check_major_version ( api_version ) <EOL> return api_version <EOL> def _get_server_version_range ( client ) : <EOL> version = client . versions . get_current ( ) <EOL> if not hasattr ( version , '<STR_LIT:version>' ) or not version . version : <EOL> return APIVersion ( ) , APIVersion ( ) <EOL> return APIVersion ( version . min_version ) , APIVersion ( version . version ) <EOL> def discover_version ( client , requested_version ) : <EOL> """<STR_LIT>""" <EOL> server_start_version , server_end_version = _get_server_version_range ( <EOL> client ) <EOL> if ( not requested_version . is_latest ( ) and <EOL> requested_version != APIVersion ( '<STR_LIT>' ) ) : <EOL> if server_start_version . is_null ( ) and server_end_version . is_null ( ) : <EOL> raise exceptions . UnsupportedVersion ( <EOL> _ ( "<STR_LIT>" ) ) <EOL> if not requested_version . matches ( server_start_version , <EOL> server_end_version ) : <EOL> raise exceptions . UnsupportedVersion ( <EOL> _ ( "<STR_LIT>" <EOL> "<STR_LIT>" ) % { <EOL> "<STR_LIT>" : server_start_version . get_string ( ) , <EOL> "<STR_LIT>" : server_end_version . get_string ( ) } ) <EOL> return requested_version <EOL> if requested_version == APIVersion ( '<STR_LIT>' ) : <EOL> if ( server_start_version == APIVersion ( '<STR_LIT>' ) or <EOL> ( server_start_version . is_null ( ) and <EOL> server_end_version . is_null ( ) ) ) : <EOL> return APIVersion ( '<STR_LIT>' ) <EOL> else : <EOL> raise exceptions . UnsupportedVersion ( <EOL> _ ( "<STR_LIT>" <EOL> "<STR_LIT>" ) ) <EOL> if server_start_version . is_null ( ) and server_end_version . is_null ( ) : <EOL> return APIVersion ( '<STR_LIT>' ) <EOL> elif cinderclient . API_MIN_VERSION > server_end_version : <EOL> raise exceptions . UnsupportedVersion ( <EOL> _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) % { <EOL> '<STR_LIT>' : cinderclient . API_MIN_VERSION . get_string ( ) , <EOL> '<STR_LIT>' : cinderclient . API_MAX_VERSION . get_string ( ) , <EOL> '<STR_LIT>' : server_start_version . get_string ( ) , <EOL> '<STR_LIT>' : server_end_version . get_string ( ) } ) <EOL> elif cinderclient . API_MAX_VERSION < server_start_version : <EOL> raise exceptions . UnsupportedVersion ( <EOL> _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) % { <EOL> '<STR_LIT>' : cinderclient . API_MIN_VERSION . get_string ( ) , <EOL> '<STR_LIT>' : cinderclient . API_MAX_VERSION . get_string ( ) , <EOL> '<STR_LIT>' : server_start_version . get_string ( ) , <EOL> '<STR_LIT>' : server_end_version . get_string ( ) } ) <EOL> elif cinderclient . API_MAX_VERSION <= server_end_version : <EOL> return cinderclient . API_MAX_VERSION <EOL> elif server_end_version < cinderclient . API_MAX_VERSION : <EOL> return server_end_version <EOL> def update_headers ( headers , api_version ) : <EOL> """<STR_LIT>""" <EOL> if not api_version . is_null ( ) and api_version . ver_minor != <NUM_LIT:0> : <EOL> headers [ "<STR_LIT>" ] = "<STR_LIT>" + api_version . get_string ( ) <EOL> def add_substitution ( versioned_method ) : <EOL> _SUBSTITUTIONS . setdefault ( versioned_method . name , [ ] ) <EOL> _SUBSTITUTIONS [ versioned_method . name ] . append ( versioned_method ) <EOL> def get_substitutions ( func_name , api_version = None ) : <EOL> substitutions = _SUBSTITUTIONS . get ( func_name , [ ] ) <EOL> if api_version and not api_version . is_null ( ) : <EOL> return [ m for m in substitutions <EOL> if api_version . matches ( m . start_version , m . end_version ) ] <EOL> return substitutions <EOL> def wraps ( start_version , end_version = None ) : <EOL> start_version = APIVersion ( start_version ) <EOL> if end_version : <EOL> end_version = APIVersion ( end_version ) <EOL> else : <EOL> end_version = APIVersion ( "<STR_LIT>" % start_version . ver_major ) <EOL> def decor ( func ) : <EOL> func . versioned = True <EOL> name = utils . get_function_name ( func ) <EOL> versioned_method = VersionedMethod ( name , start_version , <EOL> end_version , func ) <EOL> add_substitution ( versioned_method ) <EOL> @ functools . wraps ( func ) <EOL> def substitution ( obj , * args , ** kwargs ) : <EOL> methods = get_substitutions ( name , obj . api_version ) <EOL> if not methods : <EOL> raise exceptions . VersionNotFoundForAPIMethod ( <EOL> obj . api_version . get_string ( ) , name ) <EOL> method = max ( methods , key = lambda f : f . start_version ) <EOL> return method . func ( obj , * args , ** kwargs ) <EOL> if hasattr ( func , '<STR_LIT>' ) : <EOL> for cli_args , cli_kwargs in func . arguments : <EOL> utils . add_arg ( substitution , * cli_args , ** cli_kwargs ) <EOL> return substitution <EOL> return decor </s>
