<s> import copy <EOL> import os <EOL> from yaml import safe_load <EOL> class SwiftModelException ( Exception ) : <EOL> def __init__ ( self , value ) : <EOL> self . value = value <EOL> def __str__ ( self ) : <EOL> return repr ( self . value ) <EOL> class RingSpecification ( dict ) : <EOL> """<STR_LIT>""" <EOL> keynames = [ '<STR_LIT:name>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT:default>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> def __init__ ( self , parent ) : <EOL> super ( RingSpecification , self ) . __init__ ( ) <EOL> self . update ( { '<STR_LIT>' : parent } ) <EOL> def __getattr__ ( self , item ) : <EOL> if item == '<STR_LIT>' : <EOL> if self . get ( '<STR_LIT>' ) : <EOL> return float ( <EOL> self . get ( '<STR_LIT>' ) . get ( '<STR_LIT>' ) ) <EOL> elif self . get ( '<STR_LIT>' ) : <EOL> ec = self . get ( '<STR_LIT>' ) <EOL> return float ( ( ec . get ( '<STR_LIT>' ) + <EOL> ec . get ( '<STR_LIT>' ) ) ) <EOL> return None <EOL> if item in RingSpecification . keynames : <EOL> return self . get ( item , None ) <EOL> else : <EOL> raise AttributeError <EOL> def __repr__ ( self ) : <EOL> output = '<STR_LIT>' % self . name <EOL> output += '<STR_LIT>' % self . display_name <EOL> output += '<STR_LIT>' % self . partition_power <EOL> output += '<STR_LIT>' % self . __getattr__ ( '<STR_LIT>' ) <EOL> return output <EOL> def dump_model ( self ) : <EOL> model = { } <EOL> for key in self . keys ( ) : <EOL> if key not in [ '<STR_LIT>' ] : <EOL> model [ key ] = self . get ( key ) <EOL> return model <EOL> def load_model ( self , model ) : <EOL> self . update ( model ) <EOL> if not self . get ( '<STR_LIT>' , None ) : <EOL> if self . get ( '<STR_LIT:name>' ) . startswith ( '<STR_LIT>' ) : <EOL> port = <NUM_LIT> <EOL> elif self . get ( '<STR_LIT:name>' ) . startswith ( '<STR_LIT>' ) : <EOL> port = <NUM_LIT> <EOL> else : <EOL> port = <NUM_LIT> <EOL> self [ '<STR_LIT>' ] = port <EOL> if not self . get ( '<STR_LIT>' , None ) : <EOL> self [ '<STR_LIT>' ] = self . server_network_group <EOL> self [ '<STR_LIT>' ] = self . server_bind_port <EOL> if self . replication_policy and self . erasure_coding_policy : <EOL> raise SwiftModelException ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' % self . name ) <EOL> if not ( self . replication_policy or self . erasure_coding_policy ) : <EOL> raise SwiftModelException ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' % self . name ) <EOL> def get_zone ( self , rack_id ) : <EOL> """<STR_LIT>""" <EOL> if self . swift_zones : <EOL> for zone in self . swift_zones : <EOL> zone_id = zone . get ( '<STR_LIT:id>' ) <EOL> for id in zone . get ( '<STR_LIT>' ) : <EOL> if str ( rack_id ) == str ( id ) : <EOL> return zone_id <EOL> return None <EOL> else : <EOL> return - <NUM_LIT:1> <EOL> class KeystoneRegionRings ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , parent ) : <EOL> self . parent = parent <EOL> self . region_name = '<STR_LIT>' <EOL> self . swift_regions = [ ] <EOL> self . swift_zones = [ ] <EOL> self . rings = [ ] <EOL> def __repr__ ( self ) : <EOL> output = '<STR_LIT>' % self . region_name <EOL> output += '<STR_LIT>' % self . swift_regions <EOL> output += '<STR_LIT>' % self . swift_zones <EOL> output += '<STR_LIT>' <EOL> for ringspec in self . rings : <EOL> output += '<STR_LIT>' % ringspec <EOL> output += '<STR_LIT>' <EOL> return output <EOL> def load_model ( self , model ) : <EOL> self . region_name = model . get ( '<STR_LIT>' ) <EOL> for ring in model . get ( '<STR_LIT>' ) : <EOL> ringspec = RingSpecification ( self ) <EOL> ringspec . load_model ( ring ) <EOL> self . rings . append ( ringspec ) <EOL> if model . get ( '<STR_LIT>' ) : <EOL> self . swift_regions = model . get ( '<STR_LIT>' ) <EOL> if model . get ( '<STR_LIT>' ) : <EOL> self . swift_zones = model . get ( '<STR_LIT>' ) <EOL> def get_region ( self , rack_id ) : <EOL> if self . swift_regions : <EOL> for region in self . swift_regions : <EOL> region_id = region . get ( '<STR_LIT:id>' ) <EOL> for id in region . get ( '<STR_LIT>' ) : <EOL> if str ( rack_id ) == str ( id ) : <EOL> return region_id <EOL> else : <EOL> return - <NUM_LIT:1> <EOL> def get_zone ( self , rack_id ) : <EOL> if self . swift_zones : <EOL> for zone in self . swift_zones : <EOL> zone_id = zone . get ( '<STR_LIT:id>' ) <EOL> for id in zone . get ( '<STR_LIT>' ) : <EOL> if str ( rack_id ) == str ( id ) : <EOL> return zone_id <EOL> return None <EOL> else : <EOL> return - <NUM_LIT:1> <EOL> def get_region_zone ( self , ring_name , rack_id ) : <EOL> """<STR_LIT>""" <EOL> swift_region_id = self . get_region ( rack_id ) <EOL> swift_zone_id = None <EOL> for ringspec in self . rings : <EOL> if ring_name == ringspec . name : <EOL> swift_zone_id = ringspec . get_zone ( rack_id ) <EOL> if not swift_zone_id : <EOL> return ( swift_region_id , None ) <EOL> if swift_zone_id == - <NUM_LIT:1> : <EOL> swift_zone_id = self . get_zone ( rack_id ) <EOL> return swift_region_id , swift_zone_id <EOL> class RingSpecifications ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , fd = None , model = None ) : <EOL> self . keystone_ring_specifications = [ ] <EOL> if fd : <EOL> self . load_model ( safe_load ( fd ) ) <EOL> if model : <EOL> self . load_model ( model ) <EOL> def __repr__ ( self ) : <EOL> output = '<STR_LIT>' <EOL> for ksregion in self . keystone_ring_specifications : <EOL> output += '<STR_LIT>' % ksregion <EOL> return output <EOL> def load_model ( self , model ) : <EOL> ringspecs = model . get ( '<STR_LIT>' ) . get ( '<STR_LIT>' ) <EOL> for ksregion in ringspecs : <EOL> keystone_region_rings = KeystoneRegionRings ( self ) <EOL> keystone_region_rings . load_model ( ksregion ) <EOL> self . keystone_ring_specifications . append ( keystone_region_rings ) <EOL> def get_storage_policies ( self , region_name ) : <EOL> sp = { '<STR_LIT>' : [ ] } <EOL> for region_rings in self . keystone_ring_specifications : <EOL> if region_rings . region_name == region_name : <EOL> for ringspec in region_rings . rings : <EOL> if ringspec . name . startswith ( '<STR_LIT:object>' ) : <EOL> index = ringspec . name [ <NUM_LIT:7> : ] <EOL> is_default = ringspec . default <EOL> default_value = '<STR_LIT>' <EOL> if is_default : <EOL> default_value = '<STR_LIT:yes>' <EOL> attributes = { '<STR_LIT:index>' : int ( index ) , <EOL> '<STR_LIT:name>' : ringspec . display_name , <EOL> '<STR_LIT:default>' : default_value } <EOL> sp [ '<STR_LIT>' ] . append ( { '<STR_LIT>' : attributes } ) <EOL> return sp <EOL> def get_region_zone ( self , region_name , ring_name , rack_id ) : <EOL> for keystone_region_rings in self . keystone_ring_specifications : <EOL> if region_name == keystone_region_rings . region_name : <EOL> return keystone_region_rings . get_region_zone ( ring_name , <EOL> rack_id ) <EOL> break <EOL> return ( None , None ) <EOL> def get_ringspec ( self , region_name , ring_name ) : <EOL> for region_rings in self . keystone_ring_specifications : <EOL> if region_rings . region_name == region_name : <EOL> for ringspec in region_rings . rings : <EOL> if ringspec . name == ring_name : <EOL> return ringspec <EOL> def get_weight_step ( self , region_name , ring_name ) : <EOL> ringspec = self . get_ringspec ( region_name , ring_name ) <EOL> if ringspec : <EOL> weight_step = ringspec . get ( '<STR_LIT>' , None ) <EOL> if weight_step : <EOL> return float ( weight_step ) <EOL> return None <EOL> class DeviceInfo ( dict ) : <EOL> """<STR_LIT>""" <EOL> keynames = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' ] <EOL> def __init__ ( self , model = None ) : <EOL> super ( DeviceInfo , self ) . __init__ ( ) <EOL> if model : <EOL> self . load_from_model ( model ) <EOL> def __getattr__ ( self , item ) : <EOL> if item in DeviceInfo . keynames : <EOL> return self . get ( item , None ) <EOL> else : <EOL> raise AttributeError ( '<STR_LIT>' % ( item , self ) ) <EOL> def __setattr__ ( self , item , value ) : <EOL> if item in DeviceInfo . keynames : <EOL> self . update ( { item : value } ) <EOL> else : <EOL> raise AttributeError ( '<STR_LIT>' % ( item , self ) ) <EOL> def is_same_device ( self , device_info ) : <EOL> if ( self . region_name == device_info . region_name and <EOL> self . ring_name == device_info . ring_name and <EOL> self . server_ip == device_info . server_ip and <EOL> self . swift_drive_name == device_info . swift_drive_name ) : <EOL> return True <EOL> return False <EOL> def dump_model ( self ) : <EOL> return self . copy ( ) <EOL> def load_from_model ( self , model ) : <EOL> self . update ( model ) <EOL> if not self . region_name : <EOL> self [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> if not self . group_type : <EOL> self [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> if not self . presence : <EOL> self [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> if not self . balance : <EOL> self [ '<STR_LIT>' ] = <NUM_LIT:0> <EOL> if not self . meta and ( self . swift_drive_name and self . device_name ) : <EOL> self [ '<STR_LIT>' ] = '<STR_LIT>' % ( self . server_name , <EOL> self . swift_drive_name , <EOL> self . device_name ) <EOL> @ staticmethod <EOL> def sortkey ( device_info ) : <EOL> return ( device_info . region_name + device_info . ring_name + <EOL> device_info . server_ip + device_info . swift_drive_name ) <EOL> class DriveConfigurations ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> self . configurations = { } <EOL> self . drive_data = { } <EOL> def add ( self , configuration ) : <EOL> ipaddr = configuration . get ( '<STR_LIT>' ) <EOL> self . configurations [ ipaddr ] = configuration <EOL> for name , size , fulldrive in configuration . iter_drive_info ( ) : <EOL> self . drive_data [ ( ipaddr , name ) ] = ( size , fulldrive ) <EOL> def get_drive_configuration ( self , ipaddr ) : <EOL> return self . configurations . get ( ipaddr ) <EOL> def iter_drives ( self ) : <EOL> for ipaddr in self . configurations . keys ( ) : <EOL> drive_configuration = self . configurations . get ( ipaddr ) <EOL> for ( name , size , <EOL> fulldrive ) in drive_configuration . iter_drive_info ( ) : <EOL> yield ( ipaddr , name , size , fulldrive ) <EOL> def get_drive_data ( self , ipaddr , name ) : <EOL> return self . drive_data . get ( ( ipaddr , name ) , ( None , None ) ) <EOL> def get_hw ( self , ipaddr , device_info ) : <EOL> """<STR_LIT>""" <EOL> hw_size = None <EOL> if device_info . group_type == '<STR_LIT>' : <EOL> physical = device_info . block_devices . get ( '<STR_LIT>' ) [ <NUM_LIT:0> ] <EOL> hw_size , hw_fulldrive = self . get_drive_data ( ipaddr , physical ) <EOL> else : <EOL> physical_volumes_total = <NUM_LIT:0> <EOL> for physical in device_info . block_devices . get ( '<STR_LIT>' ) : <EOL> if physical . endswith ( '<STR_LIT>' ) : <EOL> physical = physical [ : - len ( '<STR_LIT>' ) ] <EOL> block_device_size , hw_fulldrive = self . get_drive_data ( <EOL> ipaddr , physical ) <EOL> if block_device_size : <EOL> physical_volumes_total += block_device_size <EOL> if physical_volumes_total : <EOL> percent_human = device_info . block_devices . get ( <EOL> '<STR_LIT>' ) <EOL> try : <EOL> percent = int ( percent_human . split ( '<STR_LIT:%>' ) [ <NUM_LIT:0> ] ) <EOL> hw_size = physical_volumes_total * percent / <NUM_LIT:100> <EOL> except ValueError : <EOL> hw_size = None <EOL> hw_fulldrive = True <EOL> return hw_size , hw_fulldrive <EOL> class DriveConfiguration ( dict ) : <EOL> """<STR_LIT>""" <EOL> keynames = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> def __init__ ( self ) : <EOL> super ( DriveConfiguration , self ) . __init__ ( ) <EOL> def load_model ( self , model ) : <EOL> self . update ( model ) <EOL> def iter_drive_info ( self ) : <EOL> """<STR_LIT>""" <EOL> for drive in self . get ( '<STR_LIT>' ) : <EOL> name = drive . get ( '<STR_LIT:name>' ) <EOL> size = drive . get ( '<STR_LIT>' ) <EOL> partitions = drive . get ( '<STR_LIT>' ) <EOL> if len ( partitions ) == <NUM_LIT:0> : <EOL> yield ( name , size , True ) <EOL> elif len ( partitions ) == <NUM_LIT:1> : <EOL> yield ( name , size , True ) <EOL> else : <EOL> yield ( name , size , False ) <EOL> for partition in partitions : <EOL> yield ( os . path . join ( '<STR_LIT>' , <EOL> partition . get ( '<STR_LIT>' ) ) , <EOL> partition . get ( '<STR_LIT>' ) , False ) <EOL> class Consumes ( object ) : <EOL> """<STR_LIT>""" <EOL> @ classmethod <EOL> def get_node_list ( cls , item , model ) : <EOL> node_list = model [ item ] [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> return node_list <EOL> @ classmethod <EOL> def basename ( cls , hostname ) : <EOL> """<STR_LIT>""" <EOL> rindex = hostname . rfind ( '<STR_LIT:->' ) <EOL> if rindex > <NUM_LIT:0> : <EOL> return hostname [ : rindex ] <EOL> else : <EOL> return hostname <EOL> def __init__ ( self , model ) : <EOL> self . nodes = { } <EOL> self . nodes [ '<STR_LIT>' ] = Consumes . get_node_list ( '<STR_LIT>' , <EOL> model ) <EOL> self . nodes [ '<STR_LIT>' ] = Consumes . get_node_list ( '<STR_LIT>' , <EOL> model ) <EOL> self . nodes [ '<STR_LIT:object>' ] = Consumes . get_node_list ( '<STR_LIT>' , <EOL> model ) <EOL> self . base_to_network = { } <EOL> for ringtype in [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:object>' ] : <EOL> for node in self . nodes [ ringtype ] : <EOL> network_name = node [ '<STR_LIT:host>' ] <EOL> network_port = node [ '<STR_LIT:port>' ] <EOL> basename = Consumes . basename ( network_name ) <EOL> self . base_to_network [ ( ringtype , basename ) ] = ( network_name , <EOL> network_port ) <EOL> def get_network_name_port ( self , ringtype , hostname ) : <EOL> """<STR_LIT>""" <EOL> if ringtype . startswith ( '<STR_LIT:object>' ) : <EOL> ringtype = '<STR_LIT:object>' <EOL> result = self . base_to_network . get ( ( ringtype , hostname ) ) <EOL> if result : <EOL> return result <EOL> basename = Consumes . basename ( hostname ) <EOL> result = self . base_to_network . get ( ( ringtype , basename ) , ( None , None ) ) <EOL> return result </s>
