<s> """<STR_LIT>""" <EOL> import abc <EOL> import copy <EOL> from oslo_utils import strutils <EOL> import six <EOL> from six . moves import http_client <EOL> from six . moves . urllib import parse <EOL> from ironicclient . common . apiclient import exceptions <EOL> from ironicclient . common . i18n import _ <EOL> def getid ( obj ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> if obj . uuid : <EOL> return obj . uuid <EOL> except AttributeError : <EOL> pass <EOL> try : <EOL> return obj . id <EOL> except AttributeError : <EOL> return obj <EOL> class HookableMixin ( object ) : <EOL> """<STR_LIT>""" <EOL> _hooks_map = { } <EOL> @ classmethod <EOL> def add_hook ( cls , hook_type , hook_func ) : <EOL> """<STR_LIT>""" <EOL> if hook_type not in cls . _hooks_map : <EOL> cls . _hooks_map [ hook_type ] = [ ] <EOL> cls . _hooks_map [ hook_type ] . append ( hook_func ) <EOL> @ classmethod <EOL> def run_hooks ( cls , hook_type , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> hook_funcs = cls . _hooks_map . get ( hook_type ) or [ ] <EOL> for hook_func in hook_funcs : <EOL> hook_func ( * args , ** kwargs ) <EOL> class BaseManager ( HookableMixin ) : <EOL> """<STR_LIT>""" <EOL> resource_class = None <EOL> def __init__ ( self , client ) : <EOL> """<STR_LIT>""" <EOL> super ( BaseManager , self ) . __init__ ( ) <EOL> self . client = client <EOL> def _list ( self , url , response_key = None , obj_class = None , json = None ) : <EOL> """<STR_LIT>""" <EOL> if json : <EOL> body = self . client . post ( url , json = json ) . json ( ) <EOL> else : <EOL> body = self . client . get ( url ) . json ( ) <EOL> if obj_class is None : <EOL> obj_class = self . resource_class <EOL> data = body [ response_key ] if response_key is not None else body <EOL> try : <EOL> data = data [ '<STR_LIT>' ] <EOL> except ( KeyError , TypeError ) : <EOL> pass <EOL> return [ obj_class ( self , res , loaded = True ) for res in data if res ] <EOL> def _get ( self , url , response_key = None ) : <EOL> """<STR_LIT>""" <EOL> body = self . client . get ( url ) . json ( ) <EOL> data = body [ response_key ] if response_key is not None else body <EOL> return self . resource_class ( self , data , loaded = True ) <EOL> def _head ( self , url ) : <EOL> """<STR_LIT>""" <EOL> resp = self . client . head ( url ) <EOL> return resp . status_code == http_client . NO_CONTENT <EOL> def _post ( self , url , json , response_key = None , return_raw = False ) : <EOL> """<STR_LIT>""" <EOL> body = self . client . post ( url , json = json ) . json ( ) <EOL> data = body [ response_key ] if response_key is not None else body <EOL> if return_raw : <EOL> return data <EOL> return self . resource_class ( self , data ) <EOL> def _put ( self , url , json = None , response_key = None ) : <EOL> """<STR_LIT>""" <EOL> resp = self . client . put ( url , json = json ) <EOL> if resp . content : <EOL> body = resp . json ( ) <EOL> if response_key is not None : <EOL> return self . resource_class ( self , body [ response_key ] ) <EOL> else : <EOL> return self . resource_class ( self , body ) <EOL> def _patch ( self , url , json = None , response_key = None ) : <EOL> """<STR_LIT>""" <EOL> body = self . client . patch ( url , json = json ) . json ( ) <EOL> if response_key is not None : <EOL> return self . resource_class ( self , body [ response_key ] ) <EOL> else : <EOL> return self . resource_class ( self , body ) <EOL> def _delete ( self , url ) : <EOL> """<STR_LIT>""" <EOL> return self . client . delete ( url ) <EOL> @ six . add_metaclass ( abc . ABCMeta ) <EOL> class ManagerWithFind ( BaseManager ) : <EOL> """<STR_LIT>""" <EOL> @ abc . abstractmethod <EOL> def list ( self ) : <EOL> pass <EOL> def find ( self , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> matches = self . findall ( ** kwargs ) <EOL> num_matches = len ( matches ) <EOL> if num_matches == <NUM_LIT:0> : <EOL> msg = _ ( "<STR_LIT>" ) % { <EOL> '<STR_LIT:name>' : self . resource_class . __name__ , <EOL> '<STR_LIT:args>' : kwargs <EOL> } <EOL> raise exceptions . NotFound ( msg ) <EOL> elif num_matches > <NUM_LIT:1> : <EOL> raise exceptions . NoUniqueMatch ( ) <EOL> else : <EOL> return matches [ <NUM_LIT:0> ] <EOL> def findall ( self , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> found = [ ] <EOL> searches = kwargs . items ( ) <EOL> for obj in self . list ( ) : <EOL> try : <EOL> if all ( getattr ( obj , attr ) == value <EOL> for ( attr , value ) in searches ) : <EOL> found . append ( obj ) <EOL> except AttributeError : <EOL> continue <EOL> return found <EOL> class CrudManager ( BaseManager ) : <EOL> """<STR_LIT>""" <EOL> collection_key = None <EOL> key = None <EOL> def build_url ( self , base_url = None , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> url = base_url if base_url is not None else '<STR_LIT>' <EOL> url += '<STR_LIT>' % self . collection_key <EOL> entity_id = kwargs . get ( '<STR_LIT>' % self . key ) <EOL> if entity_id is not None : <EOL> url += '<STR_LIT>' % entity_id <EOL> return url <EOL> def _filter_kwargs ( self , kwargs ) : <EOL> """<STR_LIT>""" <EOL> for key , ref in six . iteritems ( kwargs . copy ( ) ) : <EOL> if ref is None : <EOL> kwargs . pop ( key ) <EOL> else : <EOL> if isinstance ( ref , Resource ) : <EOL> kwargs . pop ( key ) <EOL> kwargs [ '<STR_LIT>' % key ] = getid ( ref ) <EOL> return kwargs <EOL> def create ( self , ** kwargs ) : <EOL> kwargs = self . _filter_kwargs ( kwargs ) <EOL> return self . _post ( <EOL> self . build_url ( ** kwargs ) , <EOL> { self . key : kwargs } , <EOL> self . key ) <EOL> def get ( self , ** kwargs ) : <EOL> kwargs = self . _filter_kwargs ( kwargs ) <EOL> return self . _get ( <EOL> self . build_url ( ** kwargs ) , <EOL> self . key ) <EOL> def head ( self , ** kwargs ) : <EOL> kwargs = self . _filter_kwargs ( kwargs ) <EOL> return self . _head ( self . build_url ( ** kwargs ) ) <EOL> def list ( self , base_url = None , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> kwargs = self . _filter_kwargs ( kwargs ) <EOL> return self . _list ( <EOL> '<STR_LIT>' % { <EOL> '<STR_LIT>' : self . build_url ( base_url = base_url , ** kwargs ) , <EOL> '<STR_LIT>' : '<STR_LIT>' % parse . urlencode ( kwargs ) if kwargs else '<STR_LIT>' , <EOL> } , <EOL> self . collection_key ) <EOL> def put ( self , base_url = None , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> kwargs = self . _filter_kwargs ( kwargs ) <EOL> return self . _put ( self . build_url ( base_url = base_url , ** kwargs ) ) <EOL> def update ( self , ** kwargs ) : <EOL> kwargs = self . _filter_kwargs ( kwargs ) <EOL> params = kwargs . copy ( ) <EOL> params . pop ( '<STR_LIT>' % self . key ) <EOL> return self . _patch ( <EOL> self . build_url ( ** kwargs ) , <EOL> { self . key : params } , <EOL> self . key ) <EOL> def delete ( self , ** kwargs ) : <EOL> kwargs = self . _filter_kwargs ( kwargs ) <EOL> return self . _delete ( <EOL> self . build_url ( ** kwargs ) ) <EOL> def find ( self , base_url = None , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> kwargs = self . _filter_kwargs ( kwargs ) <EOL> rl = self . _list ( <EOL> '<STR_LIT>' % { <EOL> '<STR_LIT>' : self . build_url ( base_url = base_url , ** kwargs ) , <EOL> '<STR_LIT>' : '<STR_LIT>' % parse . urlencode ( kwargs ) if kwargs else '<STR_LIT>' , <EOL> } , <EOL> self . collection_key ) <EOL> num = len ( rl ) <EOL> if num == <NUM_LIT:0> : <EOL> msg = _ ( "<STR_LIT>" ) % { <EOL> '<STR_LIT:name>' : self . resource_class . __name__ , <EOL> '<STR_LIT:args>' : kwargs <EOL> } <EOL> raise exceptions . NotFound ( msg ) <EOL> elif num > <NUM_LIT:1> : <EOL> raise exceptions . NoUniqueMatch <EOL> else : <EOL> return rl [ <NUM_LIT:0> ] <EOL> class Extension ( HookableMixin ) : <EOL> """<STR_LIT>""" <EOL> SUPPORTED_HOOKS = ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> manager_class = None <EOL> def __init__ ( self , name , module ) : <EOL> super ( Extension , self ) . __init__ ( ) <EOL> self . name = name <EOL> self . module = module <EOL> self . _parse_extension_module ( ) <EOL> def _parse_extension_module ( self ) : <EOL> self . manager_class = None <EOL> for attr_name , attr_value in self . module . __dict__ . items ( ) : <EOL> if attr_name in self . SUPPORTED_HOOKS : <EOL> self . add_hook ( attr_name , attr_value ) <EOL> else : <EOL> try : <EOL> if issubclass ( attr_value , BaseManager ) : <EOL> self . manager_class = attr_value <EOL> except TypeError : <EOL> pass <EOL> def __repr__ ( self ) : <EOL> return "<STR_LIT>" % self . name <EOL> class Resource ( object ) : <EOL> """<STR_LIT>""" <EOL> HUMAN_ID = False <EOL> NAME_ATTR = '<STR_LIT:name>' <EOL> def __init__ ( self , manager , info , loaded = False ) : <EOL> """<STR_LIT>""" <EOL> self . manager = manager <EOL> self . _info = info <EOL> self . _add_details ( info ) <EOL> self . _loaded = loaded <EOL> def __repr__ ( self ) : <EOL> reprkeys = sorted ( k <EOL> for k in self . __dict__ . keys ( ) <EOL> if k [ <NUM_LIT:0> ] != '<STR_LIT:_>' and k != '<STR_LIT>' ) <EOL> info = "<STR_LIT:U+002CU+0020>" . join ( "<STR_LIT>" % ( k , getattr ( self , k ) ) for k in reprkeys ) <EOL> return "<STR_LIT>" % ( self . __class__ . __name__ , info ) <EOL> @ property <EOL> def human_id ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . HUMAN_ID : <EOL> name = getattr ( self , self . NAME_ATTR , None ) <EOL> if name is not None : <EOL> return strutils . to_slug ( name ) <EOL> return None <EOL> def _add_details ( self , info ) : <EOL> for ( k , v ) in six . iteritems ( info ) : <EOL> try : <EOL> setattr ( self , k , v ) <EOL> self . _info [ k ] = v <EOL> except AttributeError : <EOL> pass <EOL> def __getattr__ ( self , k ) : <EOL> if k not in self . __dict__ : <EOL> if not self . is_loaded ( ) : <EOL> self . get ( ) <EOL> return self . __getattr__ ( k ) <EOL> raise AttributeError ( k ) <EOL> else : <EOL> return self . __dict__ [ k ] <EOL> def get ( self ) : <EOL> """<STR_LIT>""" <EOL> self . set_loaded ( True ) <EOL> if not hasattr ( self . manager , '<STR_LIT>' ) : <EOL> return <EOL> new = self . manager . get ( self . id ) <EOL> if new : <EOL> self . _add_details ( new . _info ) <EOL> self . _add_details ( <EOL> { '<STR_LIT>' : self . manager . client . last_request_id } ) <EOL> def __eq__ ( self , other ) : <EOL> if not isinstance ( other , Resource ) : <EOL> return NotImplemented <EOL> if not isinstance ( other , self . __class__ ) : <EOL> return False <EOL> return self . _info == other . _info <EOL> def is_loaded ( self ) : <EOL> return self . _loaded <EOL> def set_loaded ( self , val ) : <EOL> self . _loaded = val <EOL> def to_dict ( self ) : <EOL> return copy . deepcopy ( self . _info ) </s>
