signature:
def file_format ( self ) :
    """Formats device filesystem"""

implementation:
log . info ( 'Formating, can take minutes depending on flash size...' )
res = self . __exchange ( 'file.format()' , timeout = 300 )
if 'format done' not in res :
    log . error ( res )
else :
    log . info ( res )
return res


signature:
def file_print ( self , filename ) :
    """Prints a file on the device to console"""

implementation:
log . info ( 'Printing ' + filename )
res = self . __exchange ( PRINT_FILE . format ( filename = filename ) )
log . info ( res )
return res


signature:
def node_heap ( self ) :
    """Show device heap size"""

implementation:
log . info ( 'Heap' )
res = self . __exchange ( 'print(node.heap())' )
log . info ( res )
return int ( res . split ( '\r\n' ) [ 1 ] )


signature:
def node_restart ( self ) :
    """Restarts device"""

implementation:
log . info ( 'Restart' )
res = self . __exchange ( 'node.restart()' )
log . info ( res )
return res


signature:
def file_compile ( self , path ) :
    """Compiles a file specified by path on the device"""

implementation:
log . info ( 'Compile ' + path )
cmd = 'node.compile("%s")' % path
res = self . __exchange ( cmd )
log . info ( res )
return res


signature:
def file_remove ( self , path ) :
    """Removes a file on the device"""

implementation:
log . info ( 'Remove ' + path )
cmd = 'file.remove("%s")' % path
res = self . __exchange ( cmd )
log . info ( res )
return res


signature:
def backup ( self , path ) :
    """Backup all files from the device"""

implementation:
log . info ( 'Backing up in ' + path )
# List file to backup
files = self . file_list ( )
# then download each of then
self . prepare ( )
for f in files :
    self . read_file ( f [ 0 ] , os . path . join ( path , f [ 0 ] ) )


signature:
def destination_from_source ( sources , use_glob = True ) :
    """Split each of the sources in the array on ' : '
 First part will be source , second will be destination .
 Modifies the the original array to contain only sources
 and returns an array of destinations ."""

implementation:
destinations = [ ]
newsources = [ ]
for i in range ( 0 , len ( sources ) ) :
    srcdst = sources [ i ] . split ( ':' )
    if len ( srcdst ) == 2 :
        destinations . append ( srcdst [ 1 ] )
        newsources . append ( srcdst [ 0 ] )
        # proper list assignment
    else :
        if use_glob :
            listing = glob . glob ( srcdst [ 0 ] )
            for filename in listing :
                newsources . append ( filename )
                # always use forward slash at destination
                destinations . append ( filename . replace ( '\\' , '/' ) )
        else :
            newsources . append ( srcdst [ 0 ] )
            destinations . append ( srcdst [ 0 ] )
return [ newsources , destinations ]


signature:
def operation_upload ( uploader , sources , verify , do_compile , do_file , do_restart ) :
    """The upload operation"""

implementation:
sources , destinations = destination_from_source ( sources )
if len ( destinations ) == len ( sources ) :
    if uploader . prepare ( ) :
        for filename , dst in zip ( sources , destinations ) :
            if do_compile :
                uploader . file_remove ( os . path . splitext ( dst ) [ 0 ] + '.lc' )
            uploader . write_file ( filename , dst , verify )
            # init . lua is not allowed to be compiled
            if do_compile and dst != 'init.lua' :
                uploader . file_compile ( dst )
                uploader . file_remove ( dst )
                if do_file :
                    uploader . file_do ( os . path . splitext ( dst ) [ 0 ] + '.lc' )
            elif do_file :
                uploader . file_do ( dst )
    else :
        raise Exception ( 'Error preparing nodemcu for reception' )
else :
    raise Exception ( 'You must specify a destination filename for each file you want to upload.' )
if do_restart :
    uploader . node_restart ( )
log . info ( 'All done!' )


signature:
def operation_download ( uploader , sources ) :
    """The download operation"""

implementation:
sources , destinations = destination_from_source ( sources , False )
print ( 'sources' , sources )
print ( 'destinations' , destinations )
if len ( destinations ) == len ( sources ) :
    if uploader . prepare ( ) :
        for filename , dst in zip ( sources , destinations ) :
            uploader . read_file ( filename , dst )
else :
    raise Exception ( 'You must specify a destination filename for each file you want to download.' )
log . info ( 'All done!' )


signature:
def operation_list ( uploader ) :
    """List file on target"""

implementation:
files = uploader . file_list ( )
for f in files :
    log . info ( "{file:30s} {size}" . format ( file = f [ 0 ] , size = f [ 1 ] ) )


signature:
def operation_file ( uploader , cmd , filename = '' ) :
    """File operations"""

implementation:
if cmd == 'list' :
    operation_list ( uploader )
if cmd == 'do' :
    for path in filename :
        uploader . file_do ( path )
elif cmd == 'format' :
    uploader . file_format ( )
elif cmd == 'remove' :
    for path in filename :
        uploader . file_remove ( path )
elif cmd == 'print' :
    for path in filename :
        uploader . file_print ( path )


signature:
def main_func ( ) :
    """Main function for cli"""

implementation:
parser = argparse . ArgumentParser ( description = 'NodeMCU Lua file uploader' , prog = 'nodemcu-uploader' )
parser . add_argument ( '--verbose' , help = 'verbose output' , action = 'store_true' , default = False )
parser . add_argument ( '--version' , help = 'prints the version and exists' , action = 'version' , version = '%(prog)s {version} (serial {serialversion})' . format ( version = __version__ , serialversion = serialversion ) )
parser . add_argument ( '--port' , '-p' , help = 'Serial port device' , default = Uploader . PORT )
parser . add_argument ( '--baud' , '-b' , help = 'Serial port baudrate' , type = arg_auto_int , default = Uploader . BAUD )
parser . add_argument ( '--start_baud' , '-B' , help = 'Initial Serial port baudrate' , type = arg_auto_int , default = Uploader . START_BAUD )
parser . add_argument ( '--timeout' , '-t' , help = 'Timeout for operations' , type = arg_auto_int , default = Uploader . TIMEOUT )
parser . add_argument ( '--autobaud_time' , '-a' , help = 'Duration of the autobaud timer' , type = float , default = Uploader . AUTOBAUD_TIME , )
subparsers = parser . add_subparsers ( dest = 'operation' , help = 'Run nodemcu-uploader {command} -h for additional help' )
backup_parser = subparsers . add_parser ( 'backup' , help = 'Backup all the files on the nodemcu board' )
backup_parser . add_argument ( 'path' , help = 'Folder where to store the backup' )
upload_parser = subparsers . add_parser ( 'upload' , help = 'Path to one or more files to be uploaded. Destination name will be the same as the file name.' )
upload_parser . add_argument ( 'filename' , nargs = '+' , help = 'Lua file to upload. Use colon to give alternate destination.' )
upload_parser . add_argument ( '--compile' , '-c' , help = 'If file should be uploaded as compiled' , action = 'store_true' , default = False )
upload_parser . add_argument ( '--verify' , '-v' , help = 'To verify the uploaded data.' , action = 'store' , nargs = '?' , choices = [ 'none' , 'raw' , 'sha1' ] , default = 'none' )
upload_parser . add_argument ( '--dofile' , '-e' , help = 'If file should be run after upload.' , action = 'store_true' , default = False )
upload_parser . add_argument ( '--restart' , '-r' , help = 'If esp should be restarted' , action = 'store_true' , default = False )
exec_parser = subparsers . add_parser ( 'exec' , help = 'Path to one or more files to be executed line by line.' )
exec_parser . add_argument ( 'filename' , nargs = '+' , help = 'Lua file to execute.' )
download_parser = subparsers . add_parser ( 'download' , help = 'Path to one or more files to be downloaded. Destination name will be the same as the file name.' )
download_parser . add_argument ( 'filename' , nargs = '+' , help = 'Lua file to download. Use colon to give alternate destination.' )
file_parser = subparsers . add_parser ( 'file' , help = 'File functions' )
file_parser . add_argument ( 'cmd' , choices = ( 'list' , 'do' , 'format' , 'remove' , 'print' ) , help = "list=list files, do=dofile given path, format=formate file area, remove=remove given path" )
file_parser . add_argument ( 'filename' , nargs = '*' , help = 'path for cmd' )
node_parse = subparsers . add_parser ( 'node' , help = 'Node functions' )
node_parse . add_argument ( 'ncmd' , choices = ( 'heap' , 'restart' ) , help = "heap=print heap memory, restart=restart nodemcu" )
subparsers . add_parser ( 'terminal' , help = 'Run pySerials miniterm' )
args = parser . parse_args ( )
default_level = logging . INFO
if args . verbose :
    default_level = logging . DEBUG
# formatter = logging . Formatter ( ' % ( message ) s ' )
logging . basicConfig ( level = default_level , format = '%(message)s' )
if args . operation == 'terminal' : # uploader can not claim the port
    terminal ( args . port , str ( args . start_baud ) )
    return
# let uploader user the default ( short ) timeout for establishing connection
uploader = Uploader ( args . port , args . baud , start_baud = args . start_baud , autobaud_time = args . autobaud_time )
# and reset the timeout ( if we have the uploader & timeout )
if args . timeout :
    uploader . set_timeout ( args . timeout )
if args . operation == 'upload' :
    operation_upload ( uploader , args . filename , args . verify , args . compile , args . dofile , args . restart )
elif args . operation == 'download' :
    operation_download ( uploader , args . filename )
elif args . operation == 'exec' :
    sources = args . filename
    for path in sources :
        uploader . exec_file ( path )
elif args . operation == 'file' :
    operation_file ( uploader , args . cmd , args . filename )
elif args . operation == 'node' :
    if args . ncmd == 'heap' :
        uploader . node_heap ( )
    elif args . ncmd == 'restart' :
        uploader . node_restart ( )
elif args . operation == 'backup' :
    uploader . backup ( args . path )
# no uploader related commands after this point
uploader . close ( )


signature:
def display ( content ) :
    """Display a widget , text or other media in a notebook without the need to import IPython at the top level .
 Also handles wrapping GenePattern Python Library content in widgets .
 : param content :
 : return :"""

implementation:
if isinstance ( content , gp . GPServer ) :
    IPython . display . display ( GPAuthWidget ( content ) )
elif isinstance ( content , gp . GPTask ) :
    IPython . display . display ( GPTaskWidget ( content ) )
elif isinstance ( content , gp . GPJob ) :
    IPython . display . display ( GPJobWidget ( content ) )
else :
    IPython . display . display ( content )


signature:
def register ( self , server , username , password ) :
    """Register a new GenePattern server session for the provided
 server , username and password . Return the session .
 : param server :
 : param username :
 : param password :
 : return :"""

implementation:
# Create the session
session = gp . GPServer ( server , username , password )
# Validate username if not empty
valid_username = username != "" and username is not None
# Validate that the server is not already registered
index = self . _get_index ( server )
new_server = index == - 1
# Add the new session to the list
if valid_username and new_server :
    self . sessions . append ( session )
# Replace old session is one exists
if valid_username and not new_server :
    self . sessions [ index ] = session
return session


signature:
def get ( self , server ) :
    """Returns a registered GPServer object with a matching GenePattern server url or index
 Returns None if no matching result was found
 : param server :
 : return :"""

implementation:
# Handle indexes
if isinstance ( server , int ) :
    if server >= len ( self . sessions ) :
        return None
    else :
        return self . sessions [ server ]
# Handle server URLs
index = self . _get_index ( server )
if index == - 1 :
    return None
else :
    return self . sessions [ index ]


signature:
def _get_index ( self , server_url ) :
    """Returns a registered GPServer object with a matching GenePattern server url
 Returns - 1 if no matching result was found
 : param server _ url :
 : return :"""

implementation:
for i in range ( len ( self . sessions ) ) :
    session = self . sessions [ i ]
    if session . url == server_url :
        return i
return - 1


signature:
def _accept ( self , target ) :
    "Accept None or ∞ or datetime or numeric for target"

implementation:
if isinstance ( target , datetime . timedelta ) :
    target = target . total_seconds ( )
if target is None : # treat None as infinite target
    target = float ( 'Inf' )
return target


signature:
def from_timestamp ( ts ) :
    """Convert a numeric timestamp to a timezone - aware datetime .
 A client may override this function to change the default behavior ,
 such as to use local time or timezone - naïve times ."""

implementation: return datetime . datetime . utcfromtimestamp ( ts ) . replace ( tzinfo = pytz . utc )


signature:
def at_time ( cls , at , target ) :
    """Construct a DelayedCommand to come due at ` at ` , where ` at ` may be
 a datetime or timestamp ."""

implementation:
at = cls . _from_timestamp ( at )
cmd = cls . from_datetime ( at )
cmd . delay = at - now ( )
cmd . target = target
return cmd


signature:
def _localize ( dt ) :
    """Rely on pytz . localize to ensure new result honors DST ."""

implementation:
try :
    tz = dt . tzinfo
    return tz . localize ( dt . replace ( tzinfo = None ) )
except AttributeError :
    return dt


signature:
def daily_at ( cls , at , target ) :
    """Schedule a command to run at a specific time each day ."""

implementation:
daily = datetime . timedelta ( days = 1 )
# convert when to the next datetime matching this time
when = datetime . datetime . combine ( datetime . date . today ( ) , at )
if when < now ( ) :
    when += daily
return cls . at_time ( cls . _localize ( when ) , daily , target )


signature:
def strftime ( fmt , t ) :
    """A class to replace the strftime in datetime package or time module .
 Identical to strftime behavior in those modules except supports any
 year .
 Also supports datetime . datetime times .
 Also supports milliseconds using % s
 Also supports microseconds using % u"""

implementation:
if isinstance ( t , ( time . struct_time , tuple ) ) :
    t = datetime . datetime ( * t [ : 6 ] )
assert isinstance ( t , ( datetime . datetime , datetime . time , datetime . date ) )
try :
    year = t . year
    if year < 1900 :
        t = t . replace ( year = 1900 )
except AttributeError :
    year = 1900
subs = ( ( '%Y' , '%04d' % year ) , ( '%y' , '%02d' % ( year % 100 ) ) , ( '%s' , '%03d' % ( t . microsecond // 1000 ) ) , ( '%u' , '%03d' % ( t . microsecond % 1000 ) ) )
def doSub ( s , sub ) :
    return s . replace ( * sub )
def doSubs ( s ) :
    return functools . reduce ( doSub , subs , s )
fmt = '%%' . join ( map ( doSubs , fmt . split ( '%%' ) ) )
return t . strftime ( fmt )


signature:
def strptime ( s , fmt , tzinfo = None ) :
    """A function to replace strptime in the time module . Should behave
 identically to the strptime function except it returns a datetime . datetime
 object instead of a time . struct _ time object .
 Also takes an optional tzinfo parameter which is a time zone info object ."""

implementation:
res = time . strptime ( s , fmt )
return datetime . datetime ( tzinfo = tzinfo , * res [ : 6 ] )


signature:
def datetime_mod ( dt , period , start = None ) :
    """Find the time which is the specified date / time truncated to the time delta
 relative to the start date / time .
 By default , the start time is midnight of the same day as the specified
 date / time .
 > > > datetime _ mod ( datetime . datetime ( 2004 , 1 , 2 , 3 ) ,
 . . . datetime . timedelta ( days = 1.5 ) ,
 . . . start = datetime . datetime ( 2004 , 1 , 1 ) )
 datetime . datetime ( 2004 , 1 , 1 , 0 , 0)
 > > > datetime _ mod ( datetime . datetime ( 2004 , 1 , 2 , 13 ) ,
 . . . datetime . timedelta ( days = 1.5 ) ,
 . . . start = datetime . datetime ( 2004 , 1 , 1 ) )
 datetime . datetime ( 2004 , 1 , 2 , 12 , 0)
 > > > datetime _ mod ( datetime . datetime ( 2004 , 1 , 2 , 13 ) ,
 . . . datetime . timedelta ( days = 7 ) ,
 . . . start = datetime . datetime ( 2004 , 1 , 1 ) )
 datetime . datetime ( 2004 , 1 , 1 , 0 , 0)
 > > > datetime _ mod ( datetime . datetime ( 2004 , 1 , 10 , 13 ) ,
 . . . datetime . timedelta ( days = 7 ) ,
 . . . start = datetime . datetime ( 2004 , 1 , 1 ) )
 datetime . datetime ( 2004 , 1 , 8 , 0 , 0)"""

implementation:
if start is None : # use midnight of the same day
    start = datetime . datetime . combine ( dt . date ( ) , datetime . time ( ) )
# calculate the difference between the specified time and the start date .
delta = dt - start
# now aggregate the delta and the period into microseconds
# Use microseconds because that ' s the highest precision of these time
# pieces . Also , using microseconds ensures perfect precision ( no floating
# point errors ) .
def get_time_delta_microseconds ( td ) :
    return ( td . days * seconds_per_day + td . seconds ) * 1000000 + td . microseconds
delta , period = map ( get_time_delta_microseconds , ( delta , period ) )
offset = datetime . timedelta ( microseconds = delta % period )
# the result is the original specified time minus the offset
result = dt - offset
return result


signature:
def datetime_round ( dt , period , start = None ) :
    """Find the nearest even period for the specified date / time .
 > > > datetime _ round ( datetime . datetime ( 2004 , 11 , 13 , 8 , 11 , 13 ) ,
 . . . datetime . timedelta ( hours = 1 ) )
 datetime . datetime ( 2004 , 11 , 13 , 8 , 0)
 > > > datetime _ round ( datetime . datetime ( 2004 , 11 , 13 , 8 , 31 , 13 ) ,
 . . . datetime . timedelta ( hours = 1 ) )
 datetime . datetime ( 2004 , 11 , 13 , 9 , 0)
 > > > datetime _ round ( datetime . datetime ( 2004 , 11 , 13 , 8 , 30 ) ,
 . . . datetime . timedelta ( hours = 1 ) )
 datetime . datetime ( 2004 , 11 , 13 , 9 , 0)"""

implementation:
result = datetime_mod ( dt , period , start )
if abs ( dt - result ) >= period // 2 :
    result += period
return result


signature:
def get_nearest_year_for_day ( day ) :
    """Returns the nearest year to now inferred from a Julian date ."""

implementation:
now = time . gmtime ( )
result = now . tm_year
# if the day is far greater than today , it must be from last year
if day - now . tm_yday > 365 // 2 :
    result -= 1
# if the day is far less than today , it must be for next year .
if now . tm_yday - day > 365 // 2 :
    result += 1
return result


signature:
def gregorian_date ( year , julian_day ) :
    """Gregorian Date is defined as a year and a julian day ( 1 - based
 index into the days of the year ) .
 > > > gregorian _ date ( 2007 , 15)
 datetime . date ( 2007 , 1 , 15)"""

implementation:
result = datetime . date ( year , 1 , 1 )
result += datetime . timedelta ( days = julian_day - 1 )
return result


signature:
def get_period_seconds ( period ) :
    """return the number of seconds in the specified period
 > > > get _ period _ seconds ( ' day ' )
 86400
 > > > get _ period _ seconds ( 86400)
 86400
 > > > get _ period _ seconds ( datetime . timedelta ( hours = 24 ) )
 86400
 > > > get _ period _ seconds ( ' day + os . system ( " rm - Rf * " ) ' )
 Traceback ( most recent call last ) :
 ValueError : period not in ( second , minute , hour , day , month , year )"""

implementation:
if isinstance ( period , six . string_types ) :
    try :
        name = 'seconds_per_' + period . lower ( )
        result = globals ( ) [ name ]
    except KeyError :
        msg = "period not in (second, minute, hour, day, month, year)"
        raise ValueError ( msg )
elif isinstance ( period , numbers . Number ) :
    result = period
elif isinstance ( period , datetime . timedelta ) :
    result = period . days * get_period_seconds ( 'day' ) + period . seconds
else :
    raise TypeError ( 'period must be a string or integer' )
return result


signature:
def get_date_format_string ( period ) :
    """For a given period ( e . g . ' month ' , ' day ' , or some numeric interval
 such as 3600 ( in secs ) ) , return the format string that can be
 used with strftime to format that time to specify the times
 across that interval , but no more detailed .
 For example ,
 > > > get _ date _ format _ string ( ' month ' )
 ' % Y - % m '
 > > > get _ date _ format _ string ( 3600)
 ' % Y - % m - % d % H '
 > > > get _ date _ format _ string ( ' hour ' )
 ' % Y - % m - % d % H '
 > > > get _ date _ format _ string ( None )
 Traceback ( most recent call last ) :
 TypeError : period must be a string or integer
 > > > get _ date _ format _ string ( ' garbage ' )
 Traceback ( most recent call last ) :
 ValueError : period not in ( second , minute , hour , day , month , year )"""

implementation:
# handle the special case of ' month ' which doesn ' t have
# a static interval in seconds
if isinstance ( period , six . string_types ) and period . lower ( ) == 'month' :
    return '%Y-%m'
file_period_secs = get_period_seconds ( period )
format_pieces = ( '%Y' , '-%m-%d' , ' %H' , '-%M' , '-%S' )
seconds_per_second = 1
intervals = ( seconds_per_year , seconds_per_day , seconds_per_hour , seconds_per_minute , seconds_per_second , )
mods = list ( map ( lambda interval : file_period_secs % interval , intervals ) )
format_pieces = format_pieces [ : mods . index ( 0 ) + 1 ]
return '' . join ( format_pieces )


signature:
def divide_timedelta_float ( td , divisor ) :
    """Divide a timedelta by a float value
 > > > one _ day = datetime . timedelta ( days = 1)
 > > > half _ day = datetime . timedelta ( days = . 5)
 > > > divide _ timedelta _ float ( one _ day , 2.0 ) = = half _ day
 True
 > > > divide _ timedelta _ float ( one _ day , 2 ) = = half _ day
 True"""

implementation:
# td is comprised of days , seconds , microseconds
dsm = [ getattr ( td , attr ) for attr in ( 'days' , 'seconds' , 'microseconds' ) ]
dsm = map ( lambda elem : elem / divisor , dsm )
return datetime . timedelta ( * dsm )


signature:
def calculate_prorated_values ( ) :
    """A utility function to prompt for a rate ( a string in units per
 unit time ) , and return that same rate for various time periods ."""

implementation:
rate = six . moves . input ( "Enter the rate (3/hour, 50/month)> " )
res = re . match ( r'(?P<value>[\d.]+)/(?P<period>\w+)$' , rate ) . groupdict ( )
value = float ( res [ 'value' ] )
value_per_second = value / get_period_seconds ( res [ 'period' ] )
for period in ( 'minute' , 'hour' , 'day' , 'month' , 'year' ) :
    period_value = value_per_second * get_period_seconds ( period )
    print ( "per {period}: {period_value}" . format ( ** locals ( ) ) )


signature:
def parse_timedelta ( str ) :
    """Take a string representing a span of time and parse it to a time delta .
 Accepts any string of comma - separated numbers each with a unit indicator .
 > > > parse _ timedelta ( ' 1 day ' )
 datetime . timedelta ( days = 1)
 > > > parse _ timedelta ( ' 1 day , 30 seconds ' )
 datetime . timedelta ( days = 1 , seconds = 30)
 > > > parse _ timedelta ( ' 47.32 days , 20 minutes , 15.4 milliseconds ' )
 datetime . timedelta ( days = 47 , seconds = 28848 , microseconds = 15400)
 Supports weeks , months , years
 > > > parse _ timedelta ( ' 1 week ' )
 datetime . timedelta ( days = 7)
 > > > parse _ timedelta ( ' 1 year , 1 month ' )
 datetime . timedelta ( days = 395 , seconds = 58685)
 Note that months and years strict intervals , not aligned
 to a calendar :
 > > > now = datetime . datetime . now ( )
 > > > later = now + parse _ timedelta ( ' 1 year ' )
 > > > diff = later . replace ( year = now . year ) - now
 > > > diff . seconds
 20940"""

implementation:
deltas = ( _parse_timedelta_part ( part . strip ( ) ) for part in str . split ( ',' ) )
return sum ( deltas , datetime . timedelta ( ) )


signature:
def divide_timedelta ( td1 , td2 ) :
    """Get the ratio of two timedeltas
 > > > one _ day = datetime . timedelta ( days = 1)
 > > > one _ hour = datetime . timedelta ( hours = 1)
 > > > divide _ timedelta ( one _ hour , one _ day ) = = 1 / 24
 True"""

implementation:
try :
    return td1 / td2
except TypeError : # Python 3.2 gets division
# http : / / bugs . python . org / issue2706
    return td1 . total_seconds ( ) / td2 . total_seconds ( )


signature:
def date_range ( start = None , stop = None , step = None ) :
    """Much like the built - in function range , but works with dates
 > > > range _ items = date _ range (
 . . . datetime . datetime ( 2005,12,21 ) ,
 . . . datetime . datetime ( 2005,12,25 ) ,
 > > > my _ range = tuple ( range _ items )
 > > > datetime . datetime ( 2005,12,21 ) in my _ range
 True
 > > > datetime . datetime ( 2005,12,22 ) in my _ range
 True
 > > > datetime . datetime ( 2005,12,25 ) in my _ range
 False"""

implementation:
if step is None :
    step = datetime . timedelta ( days = 1 )
if start is None :
    start = datetime . datetime . now ( )
while start < stop :
    yield start
    start += step


signature:
def construct_datetime ( cls , * args , ** kwargs ) :
    """Construct a datetime . datetime from a number of different time
 types found in python and pythonwin"""

implementation:
if len ( args ) == 1 :
    arg = args [ 0 ]
    method = cls . __get_dt_constructor ( type ( arg ) . __module__ , type ( arg ) . __name__ , )
    result = method ( arg )
    try :
        result = result . replace ( tzinfo = kwargs . pop ( 'tzinfo' ) )
    except KeyError :
        pass
    if kwargs :
        first_key = kwargs . keys ( ) [ 0 ]
        tmpl = ( "{first_key} is an invalid keyword " "argument for this function." )
        raise TypeError ( tmpl . format ( ** locals ( ) ) )
else :
    result = datetime . datetime ( * args , ** kwargs )
return result


signature:
def __common_triplet ( input_string , consonants , vowels ) :
    """_ _ common _ triplet ( input _ string , consonants , vowels ) - > string"""

implementation:
output = consonants
while len ( output ) < 3 :
    try :
        output += vowels . pop ( 0 )
    except IndexError : # If there are less wovels than needed to fill the triplet ,
    # ( e . g . for a surname as " Fo ' " or " Hu " or the corean " Y " )
    # fill it with ' X ' ;
        output += 'X'
return output [ : 3 ]


signature:
def __consonants_and_vowels ( input_string ) :
    """_ _ consonants _ and _ vowels ( input _ string ) - > ( string , list )
 Get the consonants as a string and the vowels as a list ."""

implementation:
input_string = input_string . upper ( ) . replace ( ' ' , '' )
consonants = [ char for char in input_string if char in __CONSONANTS ]
vowels = [ char for char in input_string if char in __VOWELS ]
return "" . join ( consonants ) , vowels


signature:
def __surname_triplet ( input_string ) :
    """_ _ surname _ triplet ( input _ string ) - > string"""

implementation:
consonants , vowels = __consonants_and_vowels ( input_string )
return __common_triplet ( input_string , consonants , vowels )


signature:
def __name_triplet ( input_string ) :
    """_ _ name _ triplet ( input _ string ) - > string"""

implementation:
if input_string == '' : # highly unlikely : no first name , like for instance some Indian persons
# with only one name on the passport
# pylint : disable = W0511
    return 'XXX'
consonants , vowels = __consonants_and_vowels ( input_string )
if len ( consonants ) > 3 :
    return "%s%s%s" % ( consonants [ 0 ] , consonants [ 2 ] , consonants [ 3 ] )
return __common_triplet ( input_string , consonants , vowels )


signature:
def control_code ( input_string ) :
    """` ` control _ code ( input _ string ) - > int ` `
 Computes the control code for the given input _ string string . The expected
 input _ string is the first 15 characters of a fiscal code .
 eg : control _ code ( ' RCCMNL83S18D969 ' ) - > ' H '"""

implementation:
assert len ( input_string ) == 15
# building conversion tables for even and odd characters positions
even_controlcode = { }
for idx , char in enumerate ( string . digits ) :
    even_controlcode [ char ] = idx
for idx , char in enumerate ( string . ascii_uppercase ) :
    even_controlcode [ char ] = idx
values = [ 1 , 0 , 5 , 7 , 9 , 13 , 15 , 17 , 19 , 21 , 2 , 4 , 18 , 20 , 11 , 3 , 6 , 8 , 12 , 14 , 16 , 10 , 22 , 25 , 24 , 23 ]
odd_controlcode = { }
for idx , char in enumerate ( string . digits ) :
    odd_controlcode [ char ] = values [ idx ]
for idx , char in enumerate ( string . ascii_uppercase ) :
    odd_controlcode [ char ] = values [ idx ]
# computing the code
code = 0
for idx , char in enumerate ( input_string ) :
    if idx % 2 == 0 :
        code += odd_controlcode [ char ]
    else :
        code += even_controlcode [ char ]
return string . ascii_uppercase [ code % 26 ]


signature:
def build ( surname , name , birthday , sex , municipality ) :
    """` ` build ( surname , name , birthday , sex , municipality ) - > string ` `
 Computes the fiscal code for the given person data .
 eg : build ( ' Rocca ' , ' Emanuele ' , datetime . datetime ( 1983 , 11 , 18 ) , ' M ' , ' D969 ' )
 - > RCCMNL83S18D969H"""

implementation:
# RCCMNL
output = __surname_triplet ( surname ) + __name_triplet ( name )
# RCCMNL83
output += str ( birthday . year ) [ 2 : ]
# RCCMNL83S
output += MONTHSCODE [ birthday . month - 1 ]
# RCCMNL83S18
output += "%02d" % ( sex . upper ( ) == 'M' and birthday . day or 40 + birthday . day )
# RCCMNL83S18D969
output += municipality
# RCCMNL83S18D969H
output += control_code ( output )
assert isvalid ( output )
return output


signature:
def get_birthday ( code ) :
    """` ` get _ birthday ( code ) - > string ` `
 Birthday of the person whose fiscal code is ' code ' , in the format DD - MM - YY .
 Unfortunately it ' s not possible to guess the four digit birth year , given
 that the Italian fiscal code uses only the last two digits ( 1983 - > 83 ) .
 Therefore , this function returns a string and not a datetime object .
 eg : birthday ( ' RCCMNL83S18D969H ' ) - > 18-11-83"""

implementation:
assert isvalid ( code )
day = int ( code [ 9 : 11 ] )
day = day < 32 and day or day - 40
month = MONTHSCODE . index ( code [ 8 ] ) + 1
year = int ( code [ 6 : 8 ] )
return "%02d-%02d-%02d" % ( day , month , year )


signature:
def get ( self , query , responseformat = "geojson" , verbosity = "body" , build = True ) :
    """Pass in an Overpass query in Overpass QL ."""

implementation:
# Construct full Overpass query
if build :
    full_query = self . _construct_ql_query ( query , responseformat = responseformat , verbosity = verbosity )
else :
    full_query = query
if self . debug :
    logging . getLogger ( ) . info ( query )
# Get the response from Overpass
r = self . _get_from_overpass ( full_query )
content_type = r . headers . get ( "content-type" )
if self . debug :
    print ( content_type )
if content_type == "text/csv" :
    result = [ ]
    reader = csv . reader ( StringIO ( r . text ) , delimiter = "\t" )
    for row in reader :
        result . append ( row )
    return result
elif content_type in ( "text/xml" , "application/xml" , "application/osm3s+xml" ) :
    return r . text
elif content_type == "application/json" :
    response = json . loads ( r . text )
if not build :
    return response
# Check for valid answer from Overpass .
# A valid answer contains an ' elements ' key at the root level .
if "elements" not in response :
    raise UnknownOverpassError ( "Received an invalid answer from Overpass." )
# If there is a ' remark ' key , it spells trouble .
overpass_remark = response . get ( "remark" , None )
if overpass_remark and overpass_remark . startswith ( "runtime error" ) :
    raise ServerRuntimeError ( overpass_remark )
if responseformat is not "geojson" :
    return response
# construct geojson
return self . _as_geojson ( response [ "elements" ] )


signature:
def parse ( self , text ) :
    """Arguments :
 - ` self ` :
 - ` text ` :"""

implementation:
results = list ( )
for oneline in text . split ( '\n' ) :
    self . _tagger . stdin . write ( oneline + '\n' )
    while True :
        r = self . _tagger . stdout . readline ( ) [ : - 1 ]
        if not r :
            break
        results . append ( tuple ( r . split ( '\t' ) ) )
return results


signature:
def create_port ( context , port ) :
    """Create a port
 Create a port which is a connection point of a device ( e . g . , a VM
 NIC ) to attach to a L2 Neutron network .
 : param context : neutron api request context
 : param port : dictionary describing the port , with keys
 as listed in the RESOURCE _ ATTRIBUTE _ MAP object in
 neutron / api / v2 / attributes . py . All keys will be populated ."""

implementation:
LOG . info ( "create_port for tenant %s" % context . tenant_id )
port_attrs = port [ "port" ]
admin_only = [ "mac_address" , "device_owner" , "bridge" , "admin_state_up" , "use_forbidden_mac_range" , "network_plugin" , "instance_node_id" ]
utils . filter_body ( context , port_attrs , admin_only = admin_only )
port_attrs = port [ "port" ]
mac_address = utils . pop_param ( port_attrs , "mac_address" , None )
use_forbidden_mac_range = utils . pop_param ( port_attrs , "use_forbidden_mac_range" , False )
segment_id = utils . pop_param ( port_attrs , "segment_id" )
fixed_ips = utils . pop_param ( port_attrs , "fixed_ips" )
if "device_id" not in port_attrs :
    port_attrs [ 'device_id' ] = ""
device_id = port_attrs [ 'device_id' ]
# NOTE ( morgabra ) This should be instance . node from nova , only needed
# for ironic _ driver .
if "instance_node_id" not in port_attrs :
    port_attrs [ 'instance_node_id' ] = ""
instance_node_id = port_attrs [ 'instance_node_id' ]
net_id = port_attrs [ "network_id" ]
port_id = uuidutils . generate_uuid ( )
net = db_api . network_find ( context = context , limit = None , sorts = [ 'id' ] , marker = None , page_reverse = False , fields = None , id = net_id , scope = db_api . ONE )
if not net :
    raise n_exc . NetworkNotFound ( net_id = net_id )
_raise_if_unauthorized ( context , net )
# NOTE ( Perkins ) : If a device _ id is given , try to prevent multiple ports
# from being created for a device already attached to the network
if device_id :
    existing_ports = db_api . port_find ( context , network_id = net_id , device_id = device_id , scope = db_api . ONE )
    if existing_ports :
        raise n_exc . BadRequest ( resource = "port" , msg = "This device is already connected to the " "requested network via another port" )
# Try to fail early on quotas and save ourselves some db overhead
if fixed_ips :
    quota . QUOTAS . limit_check ( context , context . tenant_id , fixed_ips_per_port = len ( fixed_ips ) )
if not STRATEGY . is_provider_network ( net_id ) : # We don ' t honor segmented networks when they aren ' t " shared "
    segment_id = None
    port_count = db_api . port_count_all ( context , network_id = [ net_id ] , tenant_id = [ context . tenant_id ] )
    quota . QUOTAS . limit_check ( context , context . tenant_id , ports_per_network = port_count + 1 )
else :
    if not segment_id :
        raise q_exc . AmbiguousNetworkId ( net_id = net_id )
network_plugin = utils . pop_param ( port_attrs , "network_plugin" )
if not network_plugin :
    network_plugin = net [ "network_plugin" ]
port_attrs [ "network_plugin" ] = network_plugin
ipam_driver = _get_ipam_driver ( net , port = port_attrs )
net_driver = _get_net_driver ( net , port = port_attrs )
# NOTE ( morgabra ) It ' s possible that we select a driver different than
# the one specified by the network . However , we still might need to use
# this for some operations , so we also fetch it and pass it along to
# the backend driver we are actually using .
base_net_driver = _get_net_driver ( net )
# TODO ( anyone ) : security groups are not currently supported on port create .
# Please see JIRA : NCP - 801
security_groups = utils . pop_param ( port_attrs , "security_groups" )
if security_groups is not None :
    raise q_exc . SecurityGroupsNotImplemented ( )
group_ids , security_groups = _make_security_group_list ( context , security_groups )
quota . QUOTAS . limit_check ( context , context . tenant_id , security_groups_per_port = len ( group_ids ) )
addresses = [ ]
backend_port = None
with utils . CommandManager ( ) . execute ( ) as cmd_mgr :
    @ cmd_mgr . do
    def _allocate_ips ( fixed_ips , net , port_id , segment_id , mac , ** kwargs ) :
        if fixed_ips :
            if ( STRATEGY . is_provider_network ( net_id ) and not context . is_admin ) :
                raise n_exc . NotAuthorized ( )
            ips , subnets = split_and_validate_requested_subnets ( context , net_id , segment_id , fixed_ips )
            kwargs [ "ip_addresses" ] = ips
            kwargs [ "subnets" ] = subnets
        ipam_driver . allocate_ip_address ( context , addresses , net [ "id" ] , port_id , CONF . QUARK . ipam_reuse_after , segment_id = segment_id , mac_address = mac , ** kwargs )
    @ cmd_mgr . undo
    def _allocate_ips_undo ( addr , ** kwargs ) :
        LOG . info ( "Rolling back IP addresses..." )
        if addresses :
            for address in addresses :
                try :
                    with context . session . begin ( ) :
                        ipam_driver . deallocate_ip_address ( context , address , ** kwargs )
                except Exception :
                    LOG . exception ( "Couldn't release IP %s" % address )
    @ cmd_mgr . do
    def _allocate_mac ( net , port_id , mac_address , use_forbidden_mac_range = False , ** kwargs ) :
        mac = ipam_driver . allocate_mac_address ( context , net [ "id" ] , port_id , CONF . QUARK . ipam_reuse_after , mac_address = mac_address , use_forbidden_mac_range = use_forbidden_mac_range , ** kwargs )
        return mac
    @ cmd_mgr . undo
    def _allocate_mac_undo ( mac , ** kwargs ) :
        LOG . info ( "Rolling back MAC address..." )
        if mac :
            try :
                with context . session . begin ( ) :
                    ipam_driver . deallocate_mac_address ( context , mac [ "address" ] )
            except Exception :
                LOG . exception ( "Couldn't release MAC %s" % mac )
    @ cmd_mgr . do
    def _allocate_backend_port ( mac , addresses , net , port_id , ** kwargs ) :
        backend_port = net_driver . create_port ( context , net [ "id" ] , port_id = port_id , security_groups = group_ids , device_id = device_id , instance_node_id = instance_node_id , mac_address = mac , addresses = addresses , base_net_driver = base_net_driver )
        _filter_backend_port ( backend_port )
        return backend_port
    @ cmd_mgr . undo
    def _allocate_back_port_undo ( backend_port , ** kwargs ) :
        LOG . info ( "Rolling back backend port..." )
        try :
            backend_port_uuid = None
            if backend_port :
                backend_port_uuid = backend_port . get ( "uuid" )
            net_driver . delete_port ( context , backend_port_uuid )
        except Exception :
            LOG . exception ( "Couldn't rollback backend port %s" % backend_port )
    @ cmd_mgr . do
    def _allocate_db_port ( port_attrs , backend_port , addresses , mac , ** kwargs ) :
        port_attrs [ "network_id" ] = net [ "id" ]
        port_attrs [ "id" ] = port_id
        port_attrs [ "security_groups" ] = security_groups
        LOG . info ( "Including extra plugin attrs: %s" % backend_port )
        port_attrs . update ( backend_port )
        with context . session . begin ( ) :
            new_port = db_api . port_create ( context , addresses = addresses , mac_address = mac [ "address" ] , backend_key = backend_port [ "uuid" ] , ** port_attrs )
        return new_port
    @ cmd_mgr . undo
    def _allocate_db_port_undo ( new_port , ** kwargs ) :
        LOG . info ( "Rolling back database port..." )
        if not new_port :
            return
        try :
            with context . session . begin ( ) :
                db_api . port_delete ( context , new_port )
        except Exception :
            LOG . exception ( "Couldn't rollback db port %s" % backend_port )
    # addresses , mac , backend _ port , new _ port
    mac = _allocate_mac ( net , port_id , mac_address , use_forbidden_mac_range = use_forbidden_mac_range )
    _allocate_ips ( fixed_ips , net , port_id , segment_id , mac )
    backend_port = _allocate_backend_port ( mac , addresses , net , port_id )
    new_port = _allocate_db_port ( port_attrs , backend_port , addresses , mac )
return v . _make_port_dict ( new_port )


signature:
def update_port ( context , id , port ) :
    """Update values of a port .
 : param context : neutron api request context
 : param id : UUID representing the port to update .
 : param port : dictionary with keys indicating fields to update .
 valid keys are those that have a value of True for ' allow _ put '
 as listed in the RESOURCE _ ATTRIBUTE _ MAP object in
 neutron / api / v2 / attributes . py ."""

implementation:
LOG . info ( "update_port %s for tenant %s" % ( id , context . tenant_id ) )
port_db = db_api . port_find ( context , id = id , scope = db_api . ONE )
if not port_db :
    raise n_exc . PortNotFound ( port_id = id )
port_dict = port [ "port" ]
fixed_ips = port_dict . pop ( "fixed_ips" , None )
admin_only = [ "mac_address" , "device_owner" , "bridge" , "admin_state_up" , "device_id" ]
always_filter = [ "network_id" , "backend_key" , "network_plugin" ]
utils . filter_body ( context , port_dict , admin_only = admin_only , always_filter = always_filter )
# Pre - check the requested fixed _ ips before making too many db trips .
# Note that this is the only check we need , since this call replaces
# the entirety of the IP addresses document if fixed _ ips are provided .
if fixed_ips :
    quota . QUOTAS . limit_check ( context , context . tenant_id , fixed_ips_per_port = len ( fixed_ips ) )
new_security_groups = utils . pop_param ( port_dict , "security_groups" )
if new_security_groups is not None :
    if ( Capabilities . TENANT_NETWORK_SG not in CONF . QUARK . environment_capabilities ) :
        if not STRATEGY . is_provider_network ( port_db [ "network_id" ] ) :
            raise q_exc . TenantNetworkSecurityGroupRulesNotEnabled ( )
if new_security_groups is not None and not port_db [ "device_id" ] :
    raise q_exc . SecurityGroupsRequireDevice ( )
group_ids , security_group_mods = _make_security_group_list ( context , new_security_groups )
quota . QUOTAS . limit_check ( context , context . tenant_id , security_groups_per_port = len ( group_ids ) )
if fixed_ips is not None : # NOTE ( mdietz ) : we want full control over IPAM since
# we ' re allocating by subnet instead of
# network .
    ipam_driver = ipam . IPAM_REGISTRY . get_strategy ( ipam . QuarkIpamANY . get_name ( ) )
    addresses , subnet_ids = [ ] , [ ]
    ip_addresses = { }
    for fixed_ip in fixed_ips :
        subnet_id = fixed_ip . get ( "subnet_id" )
        ip_address = fixed_ip . get ( "ip_address" )
        if not ( subnet_id or ip_address ) :
            raise n_exc . BadRequest ( resource = "fixed_ips" , msg = "subnet_id or ip_address required" )
        if ip_address and not subnet_id :
            raise n_exc . BadRequest ( resource = "fixed_ips" , msg = "subnet_id required for ip_address allocation" )
        if subnet_id and ip_address :
            ip_netaddr = None
            try :
                ip_netaddr = netaddr . IPAddress ( ip_address ) . ipv6 ( )
            except netaddr . AddrFormatError :
                raise n_exc . InvalidInput ( error_message = "Invalid format provided for ip_address" )
            ip_addresses [ ip_netaddr ] = subnet_id
        else :
            subnet_ids . append ( subnet_id )
    port_ips = set ( [ netaddr . IPAddress ( int ( a [ "address" ] ) ) for a in port_db [ "ip_addresses" ] ] )
    new_ips = set ( [ a for a in ip_addresses . keys ( ) ] )
    ips_to_allocate = list ( new_ips - port_ips )
    ips_to_deallocate = list ( port_ips - new_ips )
    for ip in ips_to_allocate :
        if ip in ip_addresses : # NOTE : Fix for RM10187 - we were losing the list of IPs if
        # more than one IP was to be allocated . Track an
        # aggregate list instead , and add it to the running total
        # after each allocate
            allocated = [ ]
            ipam_driver . allocate_ip_address ( context , allocated , port_db [ "network_id" ] , port_db [ "id" ] , reuse_after = None , ip_addresses = [ ip ] , subnets = [ ip_addresses [ ip ] ] )
            addresses . extend ( allocated )
    for ip in ips_to_deallocate :
        ipam_driver . deallocate_ips_by_port ( context , port_db , ip_address = ip )
    for subnet_id in subnet_ids :
        ipam_driver . allocate_ip_address ( context , addresses , port_db [ "network_id" ] , port_db [ "id" ] , reuse_after = CONF . QUARK . ipam_reuse_after , subnets = [ subnet_id ] )
    # Need to return all existing addresses and the new ones
    if addresses :
        port_dict [ "addresses" ] = port_db [ "ip_addresses" ]
        port_dict [ "addresses" ] . extend ( addresses )
# NOTE ( morgabra ) Updating network _ plugin on port objects is explicitly
# disallowed in the api , so we use whatever exists in the db .
net_driver = _get_net_driver ( port_db . network , port = port_db )
base_net_driver = _get_net_driver ( port_db . network )
# TODO ( anyone ) : What do we want to have happen here if this fails ? Is it
# ok to continue to keep the IPs but fail to apply security
# groups ? Is there a clean way to have a multi - status ? Since
# we ' re in a beta - y status , I ' m going to let this sit for
# a future patch where we have time to solve it well .
kwargs = { }
if new_security_groups is not None : # TODO ( anyone ) : this is kind of silly ( when testing ) , because it will
# modify the incoming dict . Probably should be a copy or
# something .
    kwargs [ "security_groups" ] = security_group_mods
net_driver . update_port ( context , port_id = port_db [ "backend_key" ] , mac_address = port_db [ "mac_address" ] , device_id = port_db [ "device_id" ] , base_net_driver = base_net_driver , ** kwargs )
port_dict [ "security_groups" ] = security_group_mods
with context . session . begin ( ) :
    port = db_api . port_update ( context , port_db , ** port_dict )
# NOTE ( mdietz ) : fix for issue 112 , we wanted the IPs to be in
# allocated _ at order , so get a fresh object every time
if port_db in context . session :
    context . session . expunge ( port_db )
port_db = db_api . port_find ( context , id = id , scope = db_api . ONE )
return v . _make_port_dict ( port_db )


signature:
def get_port ( context , id , fields = None ) :
    """Retrieve a port .
 : param context : neutron api request context
 : param id : UUID representing the port to fetch .
 : param fields : a list of strings that are valid keys in a
 port dictionary as listed in the RESOURCE _ ATTRIBUTE _ MAP
 object in neutron / api / v2 / attributes . py . Only these fields
 will be returned ."""

implementation:
LOG . info ( "get_port %s for tenant %s fields %s" % ( id , context . tenant_id , fields ) )
results = db_api . port_find ( context , id = id , fields = fields , scope = db_api . ONE )
if not results :
    raise n_exc . PortNotFound ( port_id = id )
return v . _make_port_dict ( results )


signature:
def get_ports ( context , limit = None , sorts = [ 'id' ] , marker = None , page_reverse = False , filters = None , fields = None ) :
    """Retrieve a list of ports .
 The contents of the list depends on the identity of the user
 making the request ( as indicated by the context ) as well as any
 filters .
 : param context : neutron api request context
 : param filters : a dictionary with keys that are valid keys for
 a port as listed in the RESOURCE _ ATTRIBUTE _ MAP object
 in neutron / api / v2 / attributes . py . Values in this dictionary
 are an iterable containing values that will be used for an exact
 match comparison for that value . Each result returned by this
 function will have matched one of the values for each key in
 filters .
 : param fields : a list of strings that are valid keys in a
 port dictionary as listed in the RESOURCE _ ATTRIBUTE _ MAP
 object in neutron / api / v2 / attributes . py . Only these fields
 will be returned ."""

implementation:
LOG . info ( "get_ports for tenant %s filters %s fields %s" % ( context . tenant_id , filters , fields ) )
if filters is None :
    filters = { }
if "ip_address" in filters :
    if not context . is_admin :
        raise n_exc . NotAuthorized ( )
    ips = [ ]
    try :
        ips = [ netaddr . IPAddress ( ip ) for ip in filters . pop ( "ip_address" ) ]
    except netaddr . AddrFormatError :
        raise n_exc . InvalidInput ( error_message = "Invalid format provided for ip_address" )
    query = db_api . port_find_by_ip_address ( context , ip_address = ips , scope = db_api . ALL , ** filters )
    ports = [ ]
    for ip in query :
        ports . extend ( ip . ports )
else :
    ports = db_api . port_find ( context , limit , sorts , marker , fields = fields , join_security_groups = True , ** filters )
return v . _make_ports_list ( ports , fields )


signature:
def get_ports_count ( context , filters = None ) :
    """Return the number of ports .
 The result depends on the identity of the user making the request
 ( as indicated by the context ) as well as any filters .
 : param context : neutron api request context
 : param filters : a dictionary with keys that are valid keys for
 a port as listed in the RESOURCE _ ATTRIBUTE _ MAP object
 in neutron / api / v2 / attributes . py . Values in this dictionary
 are an iterable containing values that will be used for an exact
 match comparison for that value . Each result returned by this
 function will have matched one of the values for each key in
 filters .
 NOTE : this method is optional , as it was not part of the originally
 defined plugin API ."""

implementation:
LOG . info ( "get_ports_count for tenant %s filters %s" % ( context . tenant_id , filters ) )
return db_api . port_count_all ( context , join_security_groups = True , ** filters )


signature:
def delete_port ( context , id ) :
    """Delete a port .
 : param context : neutron api request context
 : param id : UUID representing the port to delete ."""

implementation:
LOG . info ( "delete_port %s for tenant %s" % ( id , context . tenant_id ) )
port = db_api . port_find ( context , id = id , scope = db_api . ONE )
if not port :
    raise n_exc . PortNotFound ( port_id = id )
if 'device_id' in port : # false is weird , but ignore that
    LOG . info ( "delete_port %s for tenant %s has device %s" % ( id , context . tenant_id , port [ 'device_id' ] ) )
backend_key = port [ "backend_key" ]
mac_address = netaddr . EUI ( port [ "mac_address" ] ) . value
ipam_driver = _get_ipam_driver ( port [ "network" ] , port = port )
ipam_driver . deallocate_mac_address ( context , mac_address )
ipam_driver . deallocate_ips_by_port ( context , port , ipam_reuse_after = CONF . QUARK . ipam_reuse_after )
net_driver = _get_net_driver ( port [ "network" ] , port = port )
base_net_driver = _get_net_driver ( port [ "network" ] )
net_driver . delete_port ( context , backend_key , device_id = port [ "device_id" ] , mac_address = port [ "mac_address" ] , base_net_driver = base_net_driver )
with context . session . begin ( ) :
    db_api . port_delete ( context , port )


signature:
def get_resources ( cls ) :
    """Returns Ext Resources ."""

implementation:
plugin = directory . get_plugin ( )
controller = SegmentAllocationRangesController ( plugin )
return [ extensions . ResourceExtension ( Segment_allocation_ranges . get_alias ( ) , controller ) ]


implementation:
plugin = directory . get_plugin ( )
controller = IPAvailabilityController ( plugin )
return [ extensions . ResourceExtension ( Ip_availability . get_alias ( ) , controller ) ]


signature:
def _allocate_from_v6_subnet ( self , context , net_id , subnet , port_id , reuse_after , ip_address = None , ** kwargs ) :
    """This attempts to allocate v6 addresses as per RFC2462 and RFC3041.
 To accomodate this , we effectively treat all v6 assignment as a
 first time allocation utilizing the MAC address of the VIF . Because
 we recycle MACs , we will eventually attempt to recreate a previously
 generated v6 address . Instead of failing , we ' ve opted to handle
 reallocating that address in this method .
 This should provide a performance boost over attempting to check
 each and every subnet in the existing reallocate logic , as we ' d
 have to iterate over each and every subnet returned"""

implementation:
LOG . info ( "Attempting to allocate a v6 address - [{0}]" . format ( utils . pretty_kwargs ( network_id = net_id , subnet = subnet , port_id = port_id , ip_address = ip_address ) ) )
if ip_address :
    LOG . info ( "IP %s explicitly requested, deferring to standard " "allocation" % ip_address )
    return self . _allocate_from_subnet ( context , net_id = net_id , subnet = subnet , port_id = port_id , reuse_after = reuse_after , ip_address = ip_address , ** kwargs )
else :
    mac = kwargs . get ( "mac_address" )
    if mac :
        mac = kwargs [ "mac_address" ] . get ( "address" )
    if subnet and subnet [ "ip_policy" ] :
        ip_policy_cidrs = subnet [ "ip_policy" ] . get_cidrs_ip_set ( )
    else :
        ip_policy_cidrs = netaddr . IPSet ( [ ] )
    for tries , ip_address in enumerate ( generate_v6 ( mac , port_id , subnet [ "cidr" ] ) ) :
        LOG . info ( "Attempt {0} of {1}" . format ( tries + 1 , CONF . QUARK . v6_allocation_attempts ) )
        if tries > CONF . QUARK . v6_allocation_attempts - 1 :
            LOG . info ( "Exceeded v6 allocation attempts, bailing" )
            raise ip_address_failure ( net_id )
        ip_address = netaddr . IPAddress ( ip_address ) . ipv6 ( )
        LOG . info ( "Generated a new v6 address {0}" . format ( str ( ip_address ) ) )
        if ( ip_policy_cidrs is not None and ip_address in ip_policy_cidrs ) :
            LOG . info ( "Address {0} excluded by policy" . format ( str ( ip_address ) ) )
            continue
        try :
            with context . session . begin ( ) :
                address = db_api . ip_address_create ( context , address = ip_address , subnet_id = subnet [ "id" ] , version = subnet [ "ip_version" ] , network_id = net_id , address_type = kwargs . get ( 'address_type' , ip_types . FIXED ) )
                return address
        except db_exception . DBDuplicateEntry : # This shouldn ' t ever happen , since we hold a unique MAC
        # address from the previous IPAM step .
            LOG . info ( "{0} exists but was already " "allocated" . format ( str ( ip_address ) ) )
            LOG . debug ( "Duplicate entry found when inserting subnet_id" " %s ip_address %s" , subnet [ "id" ] , ip_address )


signature:
def _create_flip ( context , flip , port_fixed_ips ) :
    """Associates the flip with ports and creates it with the flip driver
 : param context : neutron api request context .
 : param flip : quark . db . models . IPAddress object representing a floating IP
 : param port _ fixed _ ips : dictionary of the structure :
 { " < id of port > " : { " port " : < quark . db . models . Port > ,
 " fixed _ ip " : " < fixed ip address > " } }
 : return : None"""

implementation:
if port_fixed_ips :
    context . session . begin ( )
    try :
        ports = [ val [ 'port' ] for val in port_fixed_ips . values ( ) ]
        flip = db_api . port_associate_ip ( context , ports , flip , port_fixed_ips . keys ( ) )
        for port_id in port_fixed_ips :
            fixed_ip = port_fixed_ips [ port_id ] [ 'fixed_ip' ]
            flip = db_api . floating_ip_associate_fixed_ip ( context , flip , fixed_ip )
        flip_driver = registry . DRIVER_REGISTRY . get_driver ( )
        flip_driver . register_floating_ip ( flip , port_fixed_ips )
        context . session . commit ( )
    except Exception :
        context . session . rollback ( )
        raise
# alexm : Notify from this method for consistency with _ delete _ flip
billing . notify ( context , billing . IP_ASSOC , flip )


signature:
def _update_flip ( context , flip_id , ip_type , requested_ports ) :
    """Update a flip based IPAddress
 : param context : neutron api request context .
 : param flip _ id : id of the flip or scip
 : param ip _ type : ip _ types . FLOATING | ip _ types . SCALING
 : param requested _ ports : dictionary of the structure :
 { " port _ id " : " < id of port > " , " fixed _ ip " : " < fixed ip address > " }
 : return : quark . models . IPAddress"""

implementation:
# This list will hold flips that require notifications .
# Using sets to avoid dups , if any .
notifications = { billing . IP_ASSOC : set ( ) , billing . IP_DISASSOC : set ( ) }
context . session . begin ( )
try :
    flip = db_api . floating_ip_find ( context , id = flip_id , scope = db_api . ONE )
    if not flip :
        if ip_type == ip_types . SCALING :
            raise q_exc . ScalingIpNotFound ( id = flip_id )
        raise q_exc . FloatingIpNotFound ( id = flip_id )
    current_ports = flip . ports
    # Determine what ports are being removed , being added , and remain
    req_port_ids = [ request_port . get ( 'port_id' ) for request_port in requested_ports ]
    curr_port_ids = [ curr_port . id for curr_port in current_ports ]
    added_port_ids = [ port_id for port_id in req_port_ids if port_id and port_id not in curr_port_ids ]
    removed_port_ids = [ port_id for port_id in curr_port_ids if port_id not in req_port_ids ]
    remaining_port_ids = set ( curr_port_ids ) - set ( removed_port_ids )
    # Validations just for floating ip types
    if ( ip_type == ip_types . FLOATING and curr_port_ids and curr_port_ids == req_port_ids ) :
        d = dict ( flip_id = flip_id , port_id = curr_port_ids [ 0 ] )
        raise q_exc . PortAlreadyAssociatedToFloatingIp ( ** d )
    if ( ip_type == ip_types . FLOATING and not curr_port_ids and not req_port_ids ) :
        raise q_exc . FloatingIpUpdateNoPortIdSupplied ( )
    # Validate that GW IP is not in use on the NW .
    flip_subnet = v . _make_subnet_dict ( flip . subnet )
    for added_port_id in added_port_ids :
        port = _get_port ( context , added_port_id )
        nw = port . network
        nw_ports = v . _make_ports_list ( nw . ports )
        fixed_ips = [ ip . get ( 'ip_address' ) for p in nw_ports for ip in p . get ( 'fixed_ips' ) ]
        gw_ip = flip_subnet . get ( 'gateway_ip' )
        if gw_ip in fixed_ips :
            port_with_gateway_ip = None
            for port in nw_ports :
                for ip in port . get ( 'fixed_ips' ) :
                    if gw_ip in ip . get ( 'ip_address' ) :
                        port_with_gateway_ip = port
                        break
            port_id = port_with_gateway_ip . get ( 'id' )
            network_id = port_with_gateway_ip . get ( 'network_id' )
            raise q_exc . FixedIpAllocatedToGatewayIp ( port_id = port_id , network_id = network_id )
    port_fixed_ips = { }
    # Keep the ports and fixed ips that have not changed
    for port_id in remaining_port_ids :
        port = db_api . port_find ( context , id = port_id , scope = db_api . ONE )
        fixed_ip = _get_flip_fixed_ip_by_port_id ( flip , port_id )
        port_fixed_ips [ port_id ] = { 'port' : port , 'fixed_ip' : fixed_ip }
    # Disassociate the ports and fixed ips from the flip that were
    # associated to the flip but are not anymore
    for port_id in removed_port_ids :
        port = db_api . port_find ( context , id = port_id , scope = db_api . ONE )
        flip = db_api . port_disassociate_ip ( context , [ port ] , flip )
        notifications [ billing . IP_DISASSOC ] . add ( flip )
        fixed_ip = _get_flip_fixed_ip_by_port_id ( flip , port_id )
        if fixed_ip :
            flip = db_api . floating_ip_disassociate_fixed_ip ( context , flip , fixed_ip )
    # Validate the new ports with the flip and associate the new ports
    # and fixed ips with the flip
    for port_id in added_port_ids :
        port = db_api . port_find ( context , id = port_id , scope = db_api . ONE )
        if not port :
            raise n_exc . PortNotFound ( port_id = port_id )
        if any ( ip for ip in port . ip_addresses if ( ip . get ( 'address_type' ) == ip_types . FLOATING ) ) :
            raise q_exc . PortAlreadyContainsFloatingIp ( port_id = port_id )
        if any ( ip for ip in port . ip_addresses if ( ip . get ( 'address_type' ) == ip_types . SCALING ) ) :
            raise q_exc . PortAlreadyContainsScalingIp ( port_id = port_id )
        fixed_ip = _get_next_available_fixed_ip ( port )
        LOG . info ( 'new fixed ip: %s' % fixed_ip )
        if not fixed_ip :
            raise q_exc . NoAvailableFixedIpsForPort ( port_id = port_id )
        port_fixed_ips [ port_id ] = { 'port' : port , 'fixed_ip' : fixed_ip }
        flip = db_api . port_associate_ip ( context , [ port ] , flip , [ port_id ] )
        notifications [ billing . IP_ASSOC ] . add ( flip )
        flip = db_api . floating_ip_associate_fixed_ip ( context , flip , fixed_ip )
    flip_driver = registry . DRIVER_REGISTRY . get_driver ( )
    # If there are not any remaining ports and no new ones are being added ,
    # remove the floating ip from unicorn
    if not remaining_port_ids and not added_port_ids :
        flip_driver . remove_floating_ip ( flip )
    # If new ports are being added but there previously was not any ports ,
    # then register a new floating ip with the driver because it is
    # assumed it does not exist
    elif added_port_ids and not curr_port_ids :
        flip_driver . register_floating_ip ( flip , port_fixed_ips )
    else :
        flip_driver . update_floating_ip ( flip , port_fixed_ips )
    context . session . commit ( )
except Exception :
    context . session . rollback ( )
    raise
# Send notifications for possible associate / disassociate events
for notif_type , flip_set in notifications . iteritems ( ) :
    for flip in flip_set :
        billing . notify ( context , notif_type , flip )
# NOTE ( blogan ) : ORM does not seem to update the model to the real state
# of the database , so I ' m doing an explicit refresh for now .
context . session . refresh ( flip )
return flip


signature:
def create_floatingip ( context , content ) :
    """Allocate or reallocate a floating IP .
 : param context : neutron api request context .
 : param content : dictionary describing the floating ip , with keys
 as listed in the RESOURCE _ ATTRIBUTE _ MAP object in
 neutron / api / v2 / attributes . py . All keys will be populated .
 : returns : Dictionary containing details for the new floating IP . If values
 are declared in the fields parameter , then only those keys will be
 present ."""

implementation:
LOG . info ( 'create_floatingip %s for tenant %s and body %s' % ( id , context . tenant_id , content ) )
network_id = content . get ( 'floating_network_id' )
# TODO ( blogan ) : Since the extension logic will reject any requests without
# floating _ network _ id , is this still needed ?
if not network_id :
    raise n_exc . BadRequest ( resource = 'floating_ip' , msg = 'floating_network_id is required.' )
fixed_ip_address = content . get ( 'fixed_ip_address' )
ip_address = content . get ( 'floating_ip_address' )
port_id = content . get ( 'port_id' )
port = None
port_fixed_ip = { }
network = _get_network ( context , network_id )
if port_id :
    port = _get_port ( context , port_id )
    fixed_ip = _get_fixed_ip ( context , fixed_ip_address , port )
    port_fixed_ip = { port . id : { 'port' : port , 'fixed_ip' : fixed_ip } }
flip = _allocate_ip ( context , network , port , ip_address , ip_types . FLOATING )
_create_flip ( context , flip , port_fixed_ip )
return v . _make_floating_ip_dict ( flip , port_id )


signature:
def update_floatingip ( context , id , content ) :
    """Update an existing floating IP .
 : param context : neutron api request context .
 : param id : id of the floating ip
 : param content : dictionary with keys indicating fields to update .
 valid keys are those that have a value of True for ' allow _ put '
 as listed in the RESOURCE _ ATTRIBUTE _ MAP object in
 neutron / api / v2 / attributes . py .
 : returns : Dictionary containing details for the new floating IP . If values
 are declared in the fields parameter , then only those keys will be
 present ."""

implementation:
LOG . info ( 'update_floatingip %s for tenant %s and body %s' % ( id , context . tenant_id , content ) )
if 'port_id' not in content :
    raise n_exc . BadRequest ( resource = 'floating_ip' , msg = 'port_id is required.' )
requested_ports = [ ]
if content . get ( 'port_id' ) :
    requested_ports = [ { 'port_id' : content . get ( 'port_id' ) } ]
flip = _update_flip ( context , id , ip_types . FLOATING , requested_ports )
return v . _make_floating_ip_dict ( flip )


signature:
def delete_floatingip ( context , id ) :
    """deallocate a floating IP .
 : param context : neutron api request context .
 : param id : id of the floating ip"""

implementation:
LOG . info ( 'delete_floatingip %s for tenant %s' % ( id , context . tenant_id ) )
_delete_flip ( context , id , ip_types . FLOATING )


signature:
def get_floatingip ( context , id , fields = None ) :
    """Retrieve a floating IP .
 : param context : neutron api request context .
 : param id : The UUID of the floating IP .
 : param fields : a list of strings that are valid keys in a
 floating IP dictionary as listed in the RESOURCE _ ATTRIBUTE _ MAP
 object in neutron / api / v2 / attributes . py . Only these fields
 will be returned .
 : returns : Dictionary containing details for the floating IP . If values
 are declared in the fields parameter , then only those keys will be
 present ."""

implementation:
LOG . info ( 'get_floatingip %s for tenant %s' % ( id , context . tenant_id ) )
filters = { 'address_type' : ip_types . FLOATING , '_deallocated' : False }
floating_ip = db_api . floating_ip_find ( context , id = id , scope = db_api . ONE , ** filters )
if not floating_ip :
    raise q_exc . FloatingIpNotFound ( id = id )
return v . _make_floating_ip_dict ( floating_ip )


signature:
def get_floatingips ( context , filters = None , fields = None , sorts = [ 'id' ] , limit = None , marker = None , page_reverse = False ) :
    """Retrieve a list of floating ips .
 : param context : neutron api request context .
 : param filters : a dictionary with keys that are valid keys for
 a floating ip as listed in the RESOURCE _ ATTRIBUTE _ MAP object
 in neutron / api / v2 / attributes . py . Values in this dictionary
 are an iterable containing values that will be used for an exact
 match comparison for that value . Each result returned by this
 function will have matched one of the values for each key in
 filters .
 : param fields : a list of strings that are valid keys in a
 floating IP dictionary as listed in the RESOURCE _ ATTRIBUTE _ MAP
 object in neutron / api / v2 / attributes . py . Only these fields
 will be returned .
 : returns : List of floating IPs that are accessible to the tenant who
 submits the request ( as indicated by the tenant id of the context )
 as well as any filters ."""

implementation:
LOG . info ( 'get_floatingips for tenant %s filters %s fields %s' % ( context . tenant_id , filters , fields ) )
floating_ips = _get_ips_by_type ( context , ip_types . FLOATING , filters = filters , fields = fields )
return [ v . _make_floating_ip_dict ( flip ) for flip in floating_ips ]


signature:
def get_floatingips_count ( context , filters = None ) :
    """Return the number of floating IPs .
 : param context : neutron api request context
 : param filters : a dictionary with keys that are valid keys for
 a floating IP as listed in the RESOURCE _ ATTRIBUTE _ MAP object
 in neutron / api / v2 / attributes . py . Values in this dictionary
 are an iterable containing values that will be used for an exact
 match comparison for that value . Each result returned by this
 function will have matched one of the values for each key in
 filters .
 : returns : The number of floating IPs that are accessible to the tenant who
 submits the request ( as indicated by the tenant id of the context )
 as well as any filters .
 NOTE : this method is optional , as it was not part of the originally
 defined plugin API ."""

implementation:
LOG . info ( 'get_floatingips_count for tenant %s filters %s' % ( context . tenant_id , filters ) )
if filters is None :
    filters = { }
filters [ '_deallocated' ] = False
filters [ 'address_type' ] = ip_types . FLOATING
count = db_api . ip_address_count_all ( context , filters )
LOG . info ( 'Found %s floating ips for tenant %s' % ( count , context . tenant_id ) )
return count


signature:
def create_scalingip ( context , content ) :
    """Allocate or reallocate a scaling IP .
 : param context : neutron api request context .
 : param content : dictionary describing the scaling ip , with keys
 as listed in the RESOURCE _ ATTRIBUTE _ MAP object in
 neutron / api / v2 / attributes . py . All keys will be populated .
 : returns : Dictionary containing details for the new scaling IP . If values
 are declared in the fields parameter , then only those keys will be
 present ."""

implementation:
LOG . info ( 'create_scalingip for tenant %s and body %s' , context . tenant_id , content )
network_id = content . get ( 'scaling_network_id' )
ip_address = content . get ( 'scaling_ip_address' )
requested_ports = content . get ( 'ports' , [ ] )
network = _get_network ( context , network_id )
port_fixed_ips = { }
for req_port in requested_ports :
    port = _get_port ( context , req_port [ 'port_id' ] )
    fixed_ip = _get_fixed_ip ( context , req_port . get ( 'fixed_ip_address' ) , port )
    port_fixed_ips [ port . id ] = { "port" : port , "fixed_ip" : fixed_ip }
scip = _allocate_ip ( context , network , None , ip_address , ip_types . SCALING )
_create_flip ( context , scip , port_fixed_ips )
return v . _make_scaling_ip_dict ( scip )


signature:
def update_scalingip ( context , id , content ) :
    """Update an existing scaling IP .
 : param context : neutron api request context .
 : param id : id of the scaling ip
 : param content : dictionary with keys indicating fields to update .
 valid keys are those that have a value of True for ' allow _ put '
 as listed in the RESOURCE _ ATTRIBUTE _ MAP object in
 neutron / api / v2 / attributes . py .
 : returns : Dictionary containing details for the new scaling IP . If values
 are declared in the fields parameter , then only those keys will be
 present ."""

implementation:
LOG . info ( 'update_scalingip %s for tenant %s and body %s' % ( id , context . tenant_id , content ) )
requested_ports = content . get ( 'ports' , [ ] )
flip = _update_flip ( context , id , ip_types . SCALING , requested_ports )
return v . _make_scaling_ip_dict ( flip )


signature:
def delete_scalingip ( context , id ) :
    """Deallocate a scaling IP .
 : param context : neutron api request context .
 : param id : id of the scaling ip"""

implementation:
LOG . info ( 'delete_scalingip %s for tenant %s' % ( id , context . tenant_id ) )
_delete_flip ( context , id , ip_types . SCALING )


signature:
def get_scalingip ( context , id , fields = None ) :
    """Retrieve a scaling IP .
 : param context : neutron api request context .
 : param id : The UUID of the scaling IP .
 : param fields : a list of strings that are valid keys in a
 scaling IP dictionary as listed in the RESOURCE _ ATTRIBUTE _ MAP
 object in neutron / api / v2 / attributes . py . Only these fields
 will be returned .
 : returns : Dictionary containing details for the scaling IP . If values
 are declared in the fields parameter , then only those keys will be
 present ."""

implementation:
LOG . info ( 'get_scalingip %s for tenant %s' % ( id , context . tenant_id ) )
filters = { 'address_type' : ip_types . SCALING , '_deallocated' : False }
scaling_ip = db_api . floating_ip_find ( context , id = id , scope = db_api . ONE , ** filters )
if not scaling_ip :
    raise q_exc . ScalingIpNotFound ( id = id )
return v . _make_scaling_ip_dict ( scaling_ip )


signature:
def get_scalingips ( context , filters = None , fields = None , sorts = [ 'id' ] , limit = None , marker = None , page_reverse = False ) :
    """Retrieve a list of scaling ips .
 : param context : neutron api request context .
 : param filters : a dictionary with keys that are valid keys for
 a scaling ip as listed in the RESOURCE _ ATTRIBUTE _ MAP object
 in neutron / api / v2 / attributes . py . Values in this dictionary
 are an iterable containing values that will be used for an exact
 match comparison for that value . Each result returned by this
 function will have matched one of the values for each key in
 filters .
 : param fields : a list of strings that are valid keys in a
 scaling IP dictionary as listed in the RESOURCE _ ATTRIBUTE _ MAP
 object in neutron / api / v2 / attributes . py . Only these fields
 will be returned .
 : returns : List of scaling IPs that are accessible to the tenant who
 submits the request ( as indicated by the tenant id of the context )
 as well as any filters ."""

implementation:
LOG . info ( 'get_scalingips for tenant %s filters %s fields %s' % ( context . tenant_id , filters , fields ) )
scaling_ips = _get_ips_by_type ( context , ip_types . SCALING , filters = filters , fields = fields )
return [ v . _make_scaling_ip_dict ( scip ) for scip in scaling_ips ]


signature:
def update_ip_address ( context , id , ip_address ) :
    """Due to NCP - 1592 ensure that address _ type cannot change after update ."""

implementation:
LOG . info ( "update_ip_address %s for tenant %s" % ( id , context . tenant_id ) )
ports = [ ]
if 'ip_address' not in ip_address :
    raise n_exc . BadRequest ( resource = "ip_addresses" , msg = "Invalid request body." )
with context . session . begin ( ) :
    db_address = db_api . ip_address_find ( context , id = id , scope = db_api . ONE )
    if not db_address :
        raise q_exc . IpAddressNotFound ( addr_id = id )
    iptype = db_address . address_type
    if iptype == ip_types . FIXED and not CONF . QUARK . ipaddr_allow_fixed_ip :
        raise n_exc . BadRequest ( resource = "ip_addresses" , msg = "Fixed ips cannot be updated using this interface." )
    reset = ip_address [ 'ip_address' ] . get ( 'reset_allocation_time' , False )
    if reset and db_address [ 'deallocated' ] == 1 :
        if context . is_admin :
            LOG . info ( "IP's deallocated time being manually reset" )
            db_address [ 'deallocated_at' ] = _get_deallocated_override ( )
        else :
            msg = "Modification of reset_allocation_time requires admin"
            raise webob . exc . HTTPForbidden ( detail = msg )
    port_ids = ip_address [ 'ip_address' ] . get ( 'port_ids' , None )
    if port_ids is not None and not port_ids :
        raise n_exc . BadRequest ( resource = "ip_addresses" , msg = "Cannot be updated with empty port_id list" )
    if iptype == ip_types . SHARED :
        has_owner = db_address . has_any_shared_owner ( )
    if port_ids :
        if iptype == ip_types . FIXED and len ( port_ids ) > 1 :
            raise n_exc . BadRequest ( resource = "ip_addresses" , msg = "Fixed ips cannot be updated with more than one port." )
        _raise_if_shared_and_enabled ( ip_address , db_address )
        ports = db_api . port_find ( context , tenant_id = context . tenant_id , id = port_ids , scope = db_api . ALL )
        # NOTE ( name ) : could be considered inefficient because we ' re
        # converting to a list to check length . Maybe revisit
        if len ( ports ) != len ( port_ids ) :
            raise n_exc . PortNotFound ( port_id = port_ids )
        validate_and_fetch_segment ( ports , db_address [ "network_id" ] )
        validate_port_ip_quotas ( context , db_address . network_id , ports )
        if iptype == ip_types . SHARED and has_owner :
            for assoc in db_address . associations :
                pid = assoc . port_id
                if pid not in port_ids and 'none' != assoc . service :
                    raise q_exc . PortRequiresDisassociation ( )
        LOG . info ( "Updating IP address, %s, to only be used by the" "following ports:  %s" % ( db_address . address_readable , [ p . id for p in ports ] ) )
        new_address = db_api . update_port_associations_for_ip ( context , ports , db_address )
    elif iptype == ip_types . SHARED and has_owner :
        raise q_exc . PortRequiresDisassociation ( )
    elif 'deallocated' in ip_address [ 'ip_address' ] and context . is_admin : # Verify no port associations
        if len ( db_address . associations ) != 0 :
            exc_msg = ( "IP %s cannot be deallocated or allocated while" " still associated with ports: %s" % ( db_address [ 'address_readable' ] , db_address . associations ) )
            raise q_exc . ActionNotAuthorized ( msg = exc_msg )
        # NOTE : If an admin , allow a user to set deallocated to false
        # in order to reserve a deallocated IP . Alternatively , allow them
        # reverse that choice if a mistake was made .
        if ip_address [ 'ip_address' ] [ 'deallocated' ] == 'False' :
            db_address [ 'deallocated' ] = False
        else :
            db_address [ 'deallocated' ] = True
        return v . _make_ip_dict ( db_address , context . is_admin )
    else :
        ipam_driver . deallocate_ip_address ( context , db_address )
        return v . _make_ip_dict ( db_address , context . is_admin )
return v . _make_ip_dict ( new_address , context . is_admin )


signature:
def delete_ip_address ( context , id ) :
    """Delete an ip address .
 : param context : neutron api request context
 : param id : UUID representing the ip address to delete ."""

implementation:
LOG . info ( "delete_ip_address %s for tenant %s" % ( id , context . tenant_id ) )
with context . session . begin ( ) :
    ip_address = db_api . ip_address_find ( context , id = id , scope = db_api . ONE )
    if not ip_address or ip_address . deallocated :
        raise q_exc . IpAddressNotFound ( addr_id = id )
    iptype = ip_address . address_type
    if iptype == ip_types . FIXED and not CONF . QUARK . ipaddr_allow_fixed_ip :
        raise n_exc . BadRequest ( resource = "ip_addresses" , msg = "Fixed ips cannot be updated using this interface." )
    if ip_address . has_any_shared_owner ( ) :
        raise q_exc . PortRequiresDisassociation ( )
    db_api . update_port_associations_for_ip ( context , [ ] , ip_address )
    ipam_driver . deallocate_ip_address ( context , ip_address )


signature:
def get_ports_for_ip_address ( context , ip_id , limit = None , sorts = [ 'id' ] , marker = None , page_reverse = False , filters = None , fields = None ) :
    """Retrieve a list of ports .
 The contents of the list depends on the identity of the user
 making the request ( as indicated by the context ) as well as any
 filters .
 : param context : neutron api request context
 : param filters : a dictionary with keys that are valid keys for
 a port as listed in the RESOURCE _ ATTRIBUTE _ MAP object
 in neutron / api / v2 / attributes . py . Values in this dictionary
 are an iterable containing values that will be used for an exact
 match comparison for that value . Each result returned by this
 function will have matched one of the values for each key in
 filters .
 : param fields : a list of strings that are valid keys in a
 port dictionary as listed in the RESOURCE _ ATTRIBUTE _ MAP
 object in neutron / api / v2 / attributes . py . Only these fields
 will be returned ."""

implementation:
LOG . info ( "get_ports for tenant %s filters %s fields %s" % ( context . tenant_id , filters , fields ) )
addr = db_api . ip_address_find ( context , id = ip_id , scope = db_api . ONE )
if not addr :
    raise q_exc . IpAddressNotFound ( addr_id = ip_id )
if filters is None :
    filters = { }
filters [ 'ip_address_id' ] = [ ip_id ]
ports = db_api . port_find ( context , limit , sorts , marker , fields = fields , join_security_groups = True , ** filters )
return v . _make_ip_ports_list ( addr , ports , fields )


signature:
def get_port_for_ip_address ( context , ip_id , id , fields = None ) :
    """Retrieve a port .
 : param context : neutron api request context
 : param id : UUID representing the port to fetch .
 : param fields : a list of strings that are valid keys in a
 port dictionary as listed in the RESOURCE _ ATTRIBUTE _ MAP
 object in neutron / api / v2 / attributes . py . Only these fields
 will be returned ."""

implementation:
LOG . info ( "get_port %s for tenant %s fields %s" % ( id , context . tenant_id , fields ) )
addr = db_api . ip_address_find ( context , id = ip_id , scope = db_api . ONE )
if not addr :
    raise q_exc . IpAddressNotFound ( addr_id = ip_id )
filters = { 'ip_address_id' : [ ip_id ] }
results = db_api . port_find ( context , id = id , fields = fields , scope = db_api . ONE , ** filters )
if not results :
    raise n_exc . PortNotFound ( port_id = id )
return v . _make_port_for_ip_dict ( addr , results )


signature:
def update_port_for_ip_address ( context , ip_id , id , port ) :
    """Update values of a port .
 : param context : neutron api request context
 : param ip _ id : UUID representing the ip associated with port to update
 : param id : UUID representing the port to update .
 : param port : dictionary with keys indicating fields to update .
 valid keys are those that have a value of True for ' allow _ put '
 as listed in the RESOURCE _ ATTRIBUTE _ MAP object in
 neutron / api / v2 / attributes . py ."""

implementation:
LOG . info ( "update_port %s for tenant %s" % ( id , context . tenant_id ) )
sanitize_list = [ 'service' ]
with context . session . begin ( ) :
    addr = db_api . ip_address_find ( context , id = ip_id , scope = db_api . ONE )
    if not addr :
        raise q_exc . IpAddressNotFound ( addr_id = ip_id )
    port_db = db_api . port_find ( context , id = id , scope = db_api . ONE )
    if not port_db :
        raise q_exc . PortNotFound ( port_id = id )
    port_dict = { k : port [ 'port' ] [ k ] for k in sanitize_list }
    require_da = False
    service = port_dict . get ( 'service' )
    if require_da and _shared_ip_and_active ( addr , except_port = id ) :
        raise q_exc . PortRequiresDisassociation ( )
    addr . set_service_for_port ( port_db , service )
    context . session . add ( addr )
return v . _make_port_for_ip_dict ( addr , port_db )


signature:
def is_isonet_vif ( vif ) :
    """Determine if a vif is on isonet
 Returns True if a vif belongs to an isolated network by checking
 for a nicira interface id ."""

implementation:
nicira_iface_id = vif . record . get ( 'other_config' ) . get ( 'nicira-iface-id' )
if nicira_iface_id :
    return True
return False


signature:
def partition_vifs ( xapi_client , interfaces , security_group_states ) :
    """Splits VIFs into three explicit categories and one implicit
 Added - Groups exist in Redis that have not been ack ' d and the VIF
 is not tagged .
 Action : Tag the VIF and apply flows
 Updated - Groups exist in Redis that have not been ack ' d and the VIF
 is already tagged
 Action : Do not tag the VIF , do apply flows
 Removed - Groups do NOT exist in Redis but the VIF is tagged
 Action : Untag the VIF , apply default flows
 Self - Heal - Groups are ack ' d in Redis but the VIF is untagged . We treat
 this case as if it were an " added " group .
 Action : Tag the VIF and apply flows
 NOOP - The VIF is not tagged and there are no matching groups in Redis .
 This is our implicit category
 Action : Do nothing"""

implementation:
added = [ ]
updated = [ ]
removed = [ ]
for vif in interfaces : # Quark should not action on isonet vifs in regions that use FLIP
    if ( 'floating_ip' in CONF . QUARK . environment_capabilities and is_isonet_vif ( vif ) ) :
        continue
    vif_has_groups = vif in security_group_states
    if vif . tagged and vif_has_groups and security_group_states [ vif ] [ sg_cli . SECURITY_GROUP_ACK ] : # Already ack ' d these groups and VIF is tagged , reapply .
    # If it ' s not tagged , fall through and have it self - heal
        continue
    if vif . tagged :
        if vif_has_groups :
            updated . append ( vif )
        else :
            removed . append ( vif )
    else :
        if vif_has_groups :
            added . append ( vif )
        # if not tagged and no groups , skip
return added , updated , removed


signature:
def get_groups_to_ack ( groups_to_ack , init_sg_states , curr_sg_states ) :
    """Compares initial security group rules with current sg rules .
 Given the groups that were successfully returned from
 xapi _ client . update _ interfaces call , compare initial and current
 security group rules to determine if an update occurred during
 the window that the xapi _ client . update _ interfaces was executing .
 Return a list of vifs whose security group rules have not changed ."""

implementation:
security_groups_changed = [ ]
# Compare current security group rules with initial rules .
for vif in groups_to_ack :
    initial_state = init_sg_states [ vif ] [ sg_cli . SECURITY_GROUP_HASH_ATTR ]
    current_state = curr_sg_states [ vif ] [ sg_cli . SECURITY_GROUP_HASH_ATTR ]
    bad_match_msg = ( 'security group rules were changed for vif "%s" while' ' executing xapi_client.update_interfaces.' ' Will not ack rule.' % vif )
    # If lists are different lengths , they ' re automatically different .
    if len ( initial_state ) != len ( current_state ) :
        security_groups_changed . append ( vif )
        LOG . info ( bad_match_msg )
    elif len ( initial_state ) > 0 : # Compare rules in equal length lists .
        for rule in current_state :
            if rule not in initial_state :
                security_groups_changed . append ( vif )
                LOG . info ( bad_match_msg )
                break
# Only ack groups whose rules have not changed since update . If
# rules do not match , do not add them to ret so the change
# can be picked up on the next cycle .
ret = [ group for group in groups_to_ack if group not in security_groups_changed ]
return ret


signature:
def run ( ) :
    """Fetches changes and applies them to VIFs periodically
 Process as of RM11449:
 * Get all groups from redis
 * Fetch ALL VIFs from Xen
 * Walk ALL VIFs and partition them into added , updated and removed
 * Walk the final " modified " VIFs list and apply flows to each"""

implementation:
groups_client = sg_cli . SecurityGroupsClient ( )
xapi_client = xapi . XapiClient ( )
interfaces = set ( )
while True :
    try :
        interfaces = xapi_client . get_interfaces ( )
    except Exception :
        LOG . exception ( "Unable to get instances/interfaces from xapi" )
        _sleep ( )
        continue
    try :
        sg_states = groups_client . get_security_group_states ( interfaces )
        new_sg , updated_sg , removed_sg = partition_vifs ( xapi_client , interfaces , sg_states )
        xapi_client . update_interfaces ( new_sg , updated_sg , removed_sg )
        groups_to_ack = [ v for v in new_sg + updated_sg if v . success ]
        # NOTE ( quade ) : This solves a race condition where a security group
        # rule may have changed between the time the sg _ states were called
        # and when they were officially ack ' d . It functions as a compare
        # and set . This is a fix until we get onto a proper messaging
        # queue . NCP - 2287
        sg_sts_curr = groups_client . get_security_group_states ( interfaces )
        groups_to_ack = get_groups_to_ack ( groups_to_ack , sg_states , sg_sts_curr )
        # This list will contain all the security group rules that do not
        # match
        ack_groups ( groups_client , groups_to_ack )
    except Exception :
        LOG . exception ( "Unable to get security groups from registry and " "apply them to xapi" )
        _sleep ( )
        continue
    _sleep ( )


signature:
def delete_tenant_quota ( context , tenant_id ) :
    """Delete the quota entries for a given tenant _ id .
 Atfer deletion , this tenant will use default quota values in conf ."""

implementation:
tenant_quotas = context . session . query ( Quota )
tenant_quotas = tenant_quotas . filter_by ( tenant_id = tenant_id )
tenant_quotas . delete ( )


signature:
def get_resources ( cls ) :
    """Returns Ext Resources ."""

implementation:
ip_controller = IpAddressesController ( directory . get_plugin ( ) )
ip_port_controller = IpAddressPortController ( directory . get_plugin ( ) )
resources = [ ]
resources . append ( extensions . ResourceExtension ( Ip_addresses . get_alias ( ) , ip_controller ) )
parent = { 'collection_name' : 'ip_addresses' , 'member_name' : 'ip_address' }
resources . append ( extensions . ResourceExtension ( 'ports' , ip_port_controller , parent = parent ) )
return resources


signature:
def _validate_subnet_cidr ( context , network_id , new_subnet_cidr ) :
    """Validate the CIDR for a subnet .
 Verifies the specified CIDR does not overlap with the ones defined
 for the other subnets specified for this network , or with any other
 CIDR if overlapping IPs are disabled ."""

implementation:
if neutron_cfg . cfg . CONF . allow_overlapping_ips :
    return
try :
    new_subnet_ipset = netaddr . IPSet ( [ new_subnet_cidr ] )
except TypeError :
    LOG . exception ( "Invalid or missing cidr: %s" % new_subnet_cidr )
    raise n_exc . BadRequest ( resource = "subnet" , msg = "Invalid or missing cidr" )
filters = { 'network_id' : network_id , 'shared' : [ False ] }
# Using admin context here , in case we actually share networks later
subnet_list = db_api . subnet_find ( context = context . elevated ( ) , ** filters )
for subnet in subnet_list :
    if ( netaddr . IPSet ( [ subnet . cidr ] ) & new_subnet_ipset ) : # don ' t give out details of the overlapping subnet
        err_msg = ( _ ( "Requested subnet with cidr: %(cidr)s for " "network: %(network_id)s overlaps with another " "subnet" ) % { 'cidr' : new_subnet_cidr , 'network_id' : network_id } )
        LOG . error ( _ ( "Validation for CIDR: %(new_cidr)s failed - " "overlaps with subnet %(subnet_id)s " "(CIDR: %(cidr)s)" ) , { 'new_cidr' : new_subnet_cidr , 'subnet_id' : subnet . id , 'cidr' : subnet . cidr } )
        raise n_exc . InvalidInput ( error_message = err_msg )


signature:
def create_subnet ( context , subnet ) :
    """Create a subnet .
 Create a subnet which represents a range of IP addresses
 that can be allocated to devices
 : param context : neutron api request context
 : param subnet : dictionary describing the subnet , with keys
 as listed in the RESOURCE _ ATTRIBUTE _ MAP object in
 neutron / api / v2 / attributes . py . All keys will be populated ."""

implementation:
LOG . info ( "create_subnet for tenant %s" % context . tenant_id )
net_id = subnet [ "subnet" ] [ "network_id" ]
with context . session . begin ( ) :
    net = db_api . network_find ( context = context , limit = None , sorts = [ 'id' ] , marker = None , page_reverse = False , fields = None , id = net_id , scope = db_api . ONE )
    if not net :
        raise n_exc . NetworkNotFound ( net_id = net_id )
    sub_attrs = subnet [ "subnet" ]
    always_pop = [ "enable_dhcp" , "ip_version" , "first_ip" , "last_ip" , "_cidr" ]
    admin_only = [ "segment_id" , "do_not_use" , "created_at" , "next_auto_assign_ip" ]
    utils . filter_body ( context , sub_attrs , admin_only , always_pop )
    _validate_subnet_cidr ( context , net_id , sub_attrs [ "cidr" ] )
    cidr = netaddr . IPNetwork ( sub_attrs [ "cidr" ] )
    err_vals = { 'cidr' : sub_attrs [ "cidr" ] , 'network_id' : net_id }
    err = _ ( "Requested subnet with cidr: %(cidr)s for " "network: %(network_id)s. Prefix is too small, must be a " "larger subnet. A prefix less than /%(prefix)s is required." )
    if cidr . version == 6 and cidr . prefixlen > 64 :
        err_vals [ "prefix" ] = 65
        err_msg = err % err_vals
        raise n_exc . InvalidInput ( error_message = err_msg )
    elif cidr . version == 4 and cidr . prefixlen > 30 :
        err_vals [ "prefix" ] = 31
        err_msg = err % err_vals
        raise n_exc . InvalidInput ( error_message = err_msg )
    # Enforce subnet quotas
    net_subnets = get_subnets ( context , filters = dict ( network_id = net_id ) )
    if not context . is_admin :
        v4_count , v6_count = 0 , 0
        for subnet in net_subnets :
            if netaddr . IPNetwork ( subnet [ 'cidr' ] ) . version == 6 :
                v6_count += 1
            else :
                v4_count += 1
        if cidr . version == 6 :
            tenant_quota_v6 = context . session . query ( qdv . Quota ) . filter_by ( tenant_id = context . tenant_id , resource = 'v6_subnets_per_network' ) . first ( )
            if tenant_quota_v6 != - 1 :
                quota . QUOTAS . limit_check ( context , context . tenant_id , v6_subnets_per_network = v6_count + 1 )
        else :
            tenant_quota_v4 = context . session . query ( qdv . Quota ) . filter_by ( tenant_id = context . tenant_id , resource = 'v4_subnets_per_network' ) . first ( )
            if tenant_quota_v4 != - 1 :
                quota . QUOTAS . limit_check ( context , context . tenant_id , v4_subnets_per_network = v4_count + 1 )
    # See RM981 . The default behavior of setting a gateway unless
    # explicitly asked to not is no longer desirable .
    gateway_ip = utils . pop_param ( sub_attrs , "gateway_ip" )
    dns_ips = utils . pop_param ( sub_attrs , "dns_nameservers" , [ ] )
    host_routes = utils . pop_param ( sub_attrs , "host_routes" , [ ] )
    allocation_pools = utils . pop_param ( sub_attrs , "allocation_pools" , None )
    sub_attrs [ "network" ] = net
    new_subnet = db_api . subnet_create ( context , ** sub_attrs )
    cidrs = [ ]
    alloc_pools = allocation_pool . AllocationPools ( sub_attrs [ "cidr" ] , allocation_pools )
    if isinstance ( allocation_pools , list ) :
        cidrs = alloc_pools . get_policy_cidrs ( )
    quota . QUOTAS . limit_check ( context , context . tenant_id , alloc_pools_per_subnet = len ( alloc_pools ) )
    ip_policies . ensure_default_policy ( cidrs , [ new_subnet ] )
    new_subnet [ "ip_policy" ] = db_api . ip_policy_create ( context , exclude = cidrs )
    quota . QUOTAS . limit_check ( context , context . tenant_id , routes_per_subnet = len ( host_routes ) )
    default_route = None
    for route in host_routes :
        netaddr_route = netaddr . IPNetwork ( route [ "destination" ] )
        if netaddr_route . value == routes . DEFAULT_ROUTE . value :
            if default_route :
                raise q_exc . DuplicateRouteConflict ( subnet_id = new_subnet [ "id" ] )
            default_route = route
            gateway_ip = default_route [ "nexthop" ]
            alloc_pools . validate_gateway_excluded ( gateway_ip )
        new_subnet [ "routes" ] . append ( db_api . route_create ( context , cidr = route [ "destination" ] , gateway = route [ "nexthop" ] ) )
    quota . QUOTAS . limit_check ( context , context . tenant_id , dns_nameservers_per_subnet = len ( dns_ips ) )
    for dns_ip in dns_ips :
        new_subnet [ "dns_nameservers" ] . append ( db_api . dns_create ( context , ip = netaddr . IPAddress ( dns_ip ) ) )
    # if the gateway _ ip is IN the cidr for the subnet and NOT excluded by
    # policies , we should raise a 409 conflict
    if gateway_ip and default_route is None :
        alloc_pools . validate_gateway_excluded ( gateway_ip )
        new_subnet [ "routes" ] . append ( db_api . route_create ( context , cidr = str ( routes . DEFAULT_ROUTE ) , gateway = gateway_ip ) )
subnet_dict = v . _make_subnet_dict ( new_subnet )
subnet_dict [ "gateway_ip" ] = gateway_ip
return subnet_dict